From: mathnerd314 Date: Sun, 30 Aug 2009 19:45:19 +0000 (+0000) Subject: * Update squirrel to 2.2.3 X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=9c6a1aae333e63583a816badf38dbf907fa1562e;p=supertux.git * Update squirrel to 2.2.3 * Fix some script problems and improve some error messages * Minor cleanups in camera and sector git-svn-id: http://supertux.lethargik.org/svn/supertux/trunk/supertux@5912 837edb03-e0f3-0310-88ca-d4d4e8b29345 --- diff --git a/data/levels/world2/airkey.stl b/data/levels/world2/airkey.stl index 6d1a2c3fc..798c9ba36 100644 --- a/data/levels/world2/airkey.stl +++ b/data/levels/world2/airkey.stl @@ -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; }") diff --git a/data/scripts/console.nut b/data/scripts/console.nut index 5ceec2d0e..16464db49 100644 --- a/data/scripts/console.nut +++ b/data/scripts/console.nut @@ -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(); } diff --git a/src/object/camera.cpp b/src/object/camera.cpp index abdfe0c91..e6ec1926e 100644 --- a/src/object/camera.cpp +++ b/src/object/camera.cpp @@ -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; diff --git a/src/scripting/thread_queue.cpp b/src/scripting/thread_queue.cpp index 6ecaef392..2d20e47a4 100644 --- a/src/scripting/thread_queue.cpp +++ b/src/scripting/thread_queue.cpp @@ -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; } } diff --git a/src/scripting/time_scheduler.cpp b/src/scripting/time_scheduler.cpp index d28308b2f..2396d5661 100644 --- a/src/scripting/time_scheduler.cpp +++ b/src/scripting/time_scheduler.cpp @@ -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)"; diff --git a/src/sector.cpp b/src/sector.cpp index 2aa60ab17..3cb237231 100644 --- a/src/sector.cpp +++ b/src/sector.cpp @@ -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; } } } diff --git a/src/squirrel/COPYRIGHT b/src/squirrel/COPYRIGHT index 8bd208195..ad983ce26 100644 --- a/src/squirrel/COPYRIGHT +++ b/src/squirrel/COPYRIGHT @@ -1,4 +1,4 @@ -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 diff --git a/src/squirrel/HISTORY b/src/squirrel/HISTORY index 7b918084c..b6dcc8309 100644 --- a/src/squirrel/HISTORY +++ b/src/squirrel/HISTORY @@ -1,3 +1,17 @@ +***version 2.2.3 stable*** +-added sq_getfunctioninfo +-added compile time flag SQUSEDOUBLE to use double precision floats +-added global slot _floatsize_ int the base lib to recognize single precision and double precision builds +-sq_wakeupvm can now resume the vm with an exception +-added sqstd_format +-generators can now be instantiated by calling sq_call() or closure.call() +-fixed a bug in sqstd_printcallstack(thx takayuki_h) +-fixed modulo by zero(thx jup) +-fixed negative enums and constants +-fixed generator crash bug if invoked as tail call (thx Mr.Accident) +-fixed some minor bug + +***2008-09-24 *** ***version 2.2.2 stable*** -fixed some behaviour inconsistencies in thread.call() and thread.wakeup() (thx Mr.Accident) -fixed coroutine error propagation diff --git a/src/squirrel/README b/src/squirrel/README index 5b335ae67..5bd1cd4f4 100644 --- a/src/squirrel/README +++ b/src/squirrel/README @@ -1,4 +1,4 @@ -The programming language SQUIRREL 2.2.1 stable +The programming language SQUIRREL 2.2.3 stable -------------------------------------------------- The project has been compiled and run on Windows(Windows XP/2000 on Intel x86 Windows XP Pro on AMD x64) and diff --git a/src/squirrel/include/sqstdstring.h b/src/squirrel/include/sqstdstring.h index 72f30b4ad..3c3bce826 100644 --- a/src/squirrel/include/sqstdstring.h +++ b/src/squirrel/include/sqstdstring.h @@ -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 diff --git a/src/squirrel/include/squirrel.h b/src/squirrel/include/squirrel.h index 8962eb103..7d2f9a053 100644 --- a/src/squirrel/include/squirrel.h +++ b/src/squirrel/include/squirrel.h @@ -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); diff --git a/src/squirrel/sqstdlib/sqstdaux.cpp b/src/squirrel/sqstdlib/sqstdaux.cpp index f02471359..d53073be4 100644 --- a/src/squirrel/sqstdlib/sqstdaux.cpp +++ b/src/squirrel/sqstdlib/sqstdaux.cpp @@ -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; diff --git a/src/squirrel/sqstdlib/sqstdstream.cpp b/src/squirrel/sqstdlib/sqstdstream.cpp index f373f5bed..eb3e24572 100644 --- a/src/squirrel/sqstdlib/sqstdstream.cpp +++ b/src/squirrel/sqstdlib/sqstdstream.cpp @@ -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")); diff --git a/src/squirrel/sqstdlib/sqstdstream.h b/src/squirrel/sqstdlib/sqstdstream.h index 4dcc00054..2763ccb1c 100644 --- a/src/squirrel/sqstdlib/sqstdstream.h +++ b/src/squirrel/sqstdlib/sqstdstream.h @@ -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_*/ diff --git a/src/squirrel/sqstdlib/sqstdstring.cpp b/src/squirrel/sqstdlib/sqstdstring.cpp index 58e935fa8..19b30b77b 100644 --- a/src/squirrel/sqstdlib/sqstdstring.cpp +++ b/src/squirrel/sqstdlib/sqstdstring.cpp @@ -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; } diff --git a/src/squirrel/squirrel/sqapi.cpp b/src/squirrel/squirrel/sqapi.cpp index 055b4b61a..342e0a3a4 100644 --- a/src/squirrel/squirrel/sqapi.cpp +++ b/src/squirrel/squirrel/sqapi.cpp @@ -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); diff --git a/src/squirrel/squirrel/sqbaselib.cpp b/src/squirrel/squirrel/sqbaselib.cpp index 821fec98e..7a90ee25d 100644 --- a/src/squirrel/squirrel/sqbaselib.cpp +++ b/src/squirrel/squirrel/sqbaselib.cpp @@ -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) { diff --git a/src/squirrel/squirrel/sqcompiler.cpp b/src/squirrel/squirrel/sqcompiler.cpp index 5c468e1b0..a6cd2cdb2 100644 --- a/src/squirrel/squirrel/sqcompiler.cpp +++ b/src/squirrel/squirrel/sqcompiler.cpp @@ -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")); } diff --git a/src/squirrel/squirrel/sqdebug.cpp b/src/squirrel/squirrel/sqdebug.cpp index 40e0c9b99..14f7f6406 100644 --- a/src/squirrel/squirrel/sqdebug.cpp +++ b/src/squirrel/squirrel/sqdebug.cpp @@ -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; diff --git a/src/squirrel/squirrel/sqobject.h b/src/squirrel/squirrel/sqobject.h index 271bf41df..29adc3b12 100644 --- a/src/squirrel/squirrel/sqobject.h +++ b/src/squirrel/squirrel/sqobject.h @@ -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; } diff --git a/src/squirrel/squirrel/squtils.h b/src/squirrel/squirrel/squtils.h index 77ccdb2ff..b6a436e4a 100644 --- a/src/squirrel/squirrel/squtils.h +++ b/src/squirrel/squirrel/squtils.h @@ -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--; } diff --git a/src/squirrel/squirrel/sqvm.cpp b/src/squirrel/squirrel/sqvm.cpp index 7cadcafcb..9b1827ae1 100644 --- a/src/squirrel/squirrel/sqvm.cpp +++ b/src/squirrel/squirrel/sqvm.cpp @@ -16,6 +16,21 @@ #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; diff --git a/src/squirrel/squirrel/sqvm.h b/src/squirrel/squirrel/sqvm.h index b9db81751..c073fb482 100644 --- a/src/squirrel/squirrel/sqvm.h +++ b/src/squirrel/squirrel/sqvm.h @@ -53,7 +53,7 @@ struct SQVM : public CHAINABLE_OBJ typedef sqvector 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 diff --git a/src/trigger/switch.cpp b/src/trigger/switch.cpp index 82b97e13f..b32e5eded 100644 --- a/src/trigger/switch.cpp +++ b/src/trigger/switch.cpp @@ -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;