(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);
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;
}")
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();
}
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;
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;
}
}
/****** 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;
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;
}
}
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)";
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;
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
}
// Run init script
if(init_script != "") {
std::istringstream in(init_script);
- run_script(in, std::string("Sector(") + name + ") - init");
+ run_script(in, "init-script");
}
}
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;
}
}
}
-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
+***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
-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
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
/*
-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
#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;
#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
struct SQClass *pClass;
struct SQInstance *pInstance;
struct SQWeakRef *pWeakRef;
+ SQRawObjectVal raw;
}SQObjectValue;
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);
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*/
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);
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
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;
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"));
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_*/
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);
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;
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;
}
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)
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);
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);
}
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) {
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"));
}
#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;
#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
{
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);
}
SQObjectPtr(SQClass *pClass)
{
+ SQ_OBJECT_RAWINIT()
_type=OT_CLASS;
_unVal.pClass=pClass;
assert(_unVal.pClass);
}
SQObjectPtr(SQInstance *pInstance)
{
+ SQ_OBJECT_RAWINIT()
_type=OT_INSTANCE;
_unVal.pInstance=pInstance;
assert(_unVal.pInstance);
}
SQObjectPtr(SQArray *pArray)
{
+ SQ_OBJECT_RAWINIT()
_type=OT_ARRAY;
_unVal.pArray=pArray;
assert(_unVal.pArray);
}
SQObjectPtr(SQClosure *pClosure)
{
+ SQ_OBJECT_RAWINIT()
_type=OT_CLOSURE;
_unVal.pClosure=pClosure;
assert(_unVal.pClosure);
}
SQObjectPtr(SQGenerator *pGenerator)
{
+ SQ_OBJECT_RAWINIT()
_type=OT_GENERATOR;
_unVal.pGenerator=pGenerator;
assert(_unVal.pGenerator);
}
SQObjectPtr(SQNativeClosure *pNativeClosure)
{
+ SQ_OBJECT_RAWINIT()
_type=OT_NATIVECLOSURE;
_unVal.pNativeClosure=pNativeClosure;
assert(_unVal.pNativeClosure);
}
SQObjectPtr(SQString *pString)
{
+ SQ_OBJECT_RAWINIT()
_type=OT_STRING;
_unVal.pString=pString;
assert(_unVal.pString);
}
SQObjectPtr(SQUserData *pUserData)
{
+ SQ_OBJECT_RAWINIT()
_type=OT_USERDATA;
_unVal.pUserData=pUserData;
assert(_unVal.pUserData);
}
SQObjectPtr(SQVM *pThread)
{
+ SQ_OBJECT_RAWINIT()
_type=OT_THREAD;
_unVal.pThread=pThread;
assert(_unVal.pThread);
}
SQObjectPtr(SQWeakRef *pWeakRef)
{
+ SQ_OBJECT_RAWINIT()
_type=OT_WEAKREF;
_unVal.pWeakRef=pWeakRef;
assert(_unVal.pWeakRef);
}
SQObjectPtr(SQFunctionProto *pFunctionProto)
{
+ SQ_OBJECT_RAWINIT()
_type=OT_FUNCPROTO;
_unVal.pFunctionProto=pFunctionProto;
assert(_unVal.pFunctionProto);
}
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;
}
{
_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--;
}
#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;
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;
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)
}
}
- while (last_top >= _top) _stack._vals[last_top--].Null();
+ CLEARSTACK(last_top);
assert(oldstackbase >= _stackbase);
return broot?true:false;
}
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;
}
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);
_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;
}
}
_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
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;
{
inst = theclass->CreateInstance();
if(!theclass->Get(_ss(this)->_constructoridx,constructor)) {
- //if(!Call(constr,nargs,stackbase,constr,false))
- // return false;
constructor = _null_;
}
return true;
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);
_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
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;