diff --git a/src/modules/app_sqlang/squirrel/include/sqstdaux.h b/src/modules/app_sqlang/squirrel/include/sqstdaux.h index 7396add51d9..ab0849992a5 100644 --- a/src/modules/app_sqlang/squirrel/include/sqstdaux.h +++ b/src/modules/app_sqlang/squirrel/include/sqstdaux.h @@ -9,6 +9,8 @@ extern "C" { SQUIRREL_API void sqstd_seterrorhandlers(HSQUIRRELVM v); SQUIRREL_API void sqstd_printcallstack(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sqstd_throwerrorf(HSQUIRRELVM v,const SQChar *err,...); + #ifdef __cplusplus } /*extern "C"*/ #endif diff --git a/src/modules/app_sqlang/squirrel/include/sqstdstring.h b/src/modules/app_sqlang/squirrel/include/sqstdstring.h index e7ecbed62e0..3209a2d9e2e 100644 --- a/src/modules/app_sqlang/squirrel/include/sqstdstring.h +++ b/src/modules/app_sqlang/squirrel/include/sqstdstring.h @@ -24,6 +24,8 @@ SQUIRREL_API SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *sub SQUIRREL_API SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output); +SQUIRREL_API void sqstd_pushstringf(HSQUIRRELVM v,const SQChar *s,...); + SQUIRREL_API SQRESULT sqstd_register_stringlib(HSQUIRRELVM v); #ifdef __cplusplus diff --git a/src/modules/app_sqlang/squirrel/include/squirrel.h b/src/modules/app_sqlang/squirrel/include/squirrel.h index c4c338370f5..19ed82fd9ef 100644 --- a/src/modules/app_sqlang/squirrel/include/squirrel.h +++ b/src/modules/app_sqlang/squirrel/include/squirrel.h @@ -276,7 +276,7 @@ SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK ho SQUIRREL_API SQRELEASEHOOK sq_getreleasehook(HSQUIRRELVM v,SQInteger idx); SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize); SQUIRREL_API SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger level,SQFunctionInfo *fi); -SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars); +SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQInteger *nparams,SQInteger *nfreevars); SQUIRREL_API SQRESULT sq_getclosurename(HSQUIRRELVM v,SQInteger idx); 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/modules/app_sqlang/squirrel/sqstdlib/sqstdaux.cpp b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdaux.cpp index 3c478fcfef7..75c165339fb 100644 --- a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdaux.cpp +++ b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdaux.cpp @@ -1,7 +1,9 @@ /* see copyright notice in squirrel.h */ #include #include +#include #include +#include void sqstd_printcallstack(HSQUIRRELVM v) { @@ -128,3 +130,22 @@ void sqstd_seterrorhandlers(HSQUIRRELVM v) sq_newclosure(v,_sqstd_aux_printerror,0); sq_seterrorhandler(v); } + +SQRESULT sqstd_throwerrorf(HSQUIRRELVM v,const SQChar *err,...) +{ + SQInteger n=256; + va_list args; +begin: + va_start(args,err); + SQChar *b=sq_getscratchpad(v,n); + SQInteger r=scvsprintf(b,n,err,args); + va_end(args); + if (r>=n) { + n=r+1;//required+null + goto begin; + } else if (r<0) { + return sq_throwerror(v,_SC("@failed to generate formatted error message")); + } else { + return sq_throwerror(v,b); + } +} diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstring.cpp b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstring.cpp index e624646f469..7f7599bbfb4 100644 --- a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstring.cpp +++ b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstring.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #define MAX_FORMAT_LEN 20 #define MAX_WFORMAT_LEN 3 @@ -153,6 +154,25 @@ SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen return SQ_OK; } +void sqstd_pushstringf(HSQUIRRELVM v,const SQChar *s,...) +{ + SQInteger n=256; + va_list args; +begin: + va_start(args,s); + SQChar *b=sq_getscratchpad(v,n); + SQInteger r=scvsprintf(b,n,s,args); + va_end(args); + if (r>=n) { + n=r+1;//required+null + goto begin; + } else if (r<0) { + sq_pushnull(v); + } else { + sq_pushstring(v,b,r); + } +} + static SQInteger _string_printf(HSQUIRRELVM v) { SQChar *dest = NULL; diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqapi.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqapi.cpp index e4e82767c4c..a3221503da5 100644 --- a/src/modules/app_sqlang/squirrel/squirrel/sqapi.cpp +++ b/src/modules/app_sqlang/squirrel/squirrel/sqapi.cpp @@ -394,21 +394,21 @@ void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars) v->Push(SQObjectPtr(nc)); } -SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars) +SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQInteger *nparams,SQInteger *nfreevars) { SQObject o = stack_get(v, idx); if(sq_type(o) == OT_CLOSURE) { SQClosure *c = _closure(o); SQFunctionProto *proto = c->_function; - *nparams = (SQUnsignedInteger)proto->_nparameters; - *nfreevars = (SQUnsignedInteger)proto->_noutervalues; + *nparams = proto->_nparameters; + *nfreevars = proto->_noutervalues; return SQ_OK; } else if(sq_type(o) == OT_NATIVECLOSURE) { SQNativeClosure *c = _nativeclosure(o); - *nparams = (SQUnsignedInteger)c->_nparamscheck; - *nfreevars = c->_noutervalues; + *nparams = c->_nparamscheck; + *nfreevars = (SQInteger)c->_noutervalues; return SQ_OK; } return sq_throwerror(v,_SC("the object is not a closure")); @@ -978,7 +978,7 @@ SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx) case OT_TABLE: if(sq_type(mt) == OT_TABLE) { if(!_table(self)->SetDelegate(_table(mt))) { - return sq_throwerror(v, _SC("delagate cycle")); + return sq_throwerror(v, _SC("delegate cycle")); } v->Pop(); } @@ -1175,23 +1175,15 @@ SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror) SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror) { SQObjectPtr res; - if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false)){ - - if(!v->_suspended) { - v->Pop(params);//pop args - } - if(retval){ - v->Push(res); return SQ_OK; - } - return SQ_OK; - } - else { - v->Pop(params); + if(!v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false)){ + v->Pop(params); //pop args return SQ_ERROR; } if(!v->_suspended) - v->Pop(params); - return sq_throwerror(v,_SC("call failed")); + v->Pop(params); //pop args + if(retval) + v->Push(res); // push result + return SQ_OK; } SQRESULT sq_tailcall(HSQUIRRELVM v, SQInteger nparams) diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqbaselib.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqbaselib.cpp index 52527886fbc..f3b8103185d 100644 --- a/src/modules/app_sqlang/squirrel/squirrel/sqbaselib.cpp +++ b/src/modules/app_sqlang/squirrel/squirrel/sqbaselib.cpp @@ -413,7 +413,7 @@ static SQInteger obj_delegate_weakref(HSQUIRRELVM v) static SQInteger obj_clear(HSQUIRRELVM v) { - return sq_clear(v,-1); + return SQ_SUCCEEDED(sq_clear(v,-1)) ? 1 : SQ_ERROR; } @@ -450,7 +450,7 @@ static SQInteger container_rawexists(HSQUIRRELVM v) static SQInteger container_rawset(HSQUIRRELVM v) { - return sq_rawset(v,-3); + return SQ_SUCCEEDED(sq_rawset(v,-3)) ? 1 : SQ_ERROR; } @@ -499,6 +499,30 @@ static SQInteger table_filter(HSQUIRRELVM v) return 1; } +#define TABLE_TO_ARRAY_FUNC(_funcname_,_valname_) static SQInteger _funcname_(HSQUIRRELVM v) \ +{ \ + SQObject &o = stack_get(v, 1); \ + SQTable *t = _table(o); \ + SQObjectPtr itr, key, val; \ + SQObjectPtr _null; \ + SQInteger nitr, n = 0; \ + SQInteger nitems = t->CountUsed(); \ + SQArray *a = SQArray::Create(_ss(v), nitems); \ + a->Resize(nitems, _null); \ + if (nitems) { \ + while ((nitr = t->Next(false, itr, key, val)) != -1) { \ + itr = (SQInteger)nitr; \ + a->Set(n, _valname_); \ + n++; \ + } \ + } \ + v->Push(a); \ + return 1; \ +} + +TABLE_TO_ARRAY_FUNC(table_keys, key) +TABLE_TO_ARRAY_FUNC(table_values, val) + const SQRegFunction SQSharedState::_table_default_delegate_funcz[]={ {_SC("len"),default_delegate_len,1, _SC("t")}, @@ -512,6 +536,8 @@ const SQRegFunction SQSharedState::_table_default_delegate_funcz[]={ {_SC("setdelegate"),table_setdelegate,2, _SC(".t|o")}, {_SC("getdelegate"),table_getdelegate,1, _SC(".")}, {_SC("filter"),table_filter,2, _SC("tc")}, + {_SC("keys"),table_keys,1, _SC("t") }, + {_SC("values"),table_values,1, _SC("t") }, {NULL,(SQFUNCTION)0,0,NULL} }; @@ -519,18 +545,19 @@ const SQRegFunction SQSharedState::_table_default_delegate_funcz[]={ static SQInteger array_append(HSQUIRRELVM v) { - return sq_arrayappend(v,-2); + return SQ_SUCCEEDED(sq_arrayappend(v,-2)) ? 1 : SQ_ERROR; } static SQInteger array_extend(HSQUIRRELVM v) { _array(stack_get(v,1))->Extend(_array(stack_get(v,2))); - return 0; + sq_pop(v,1); + return 1; } static SQInteger array_reverse(HSQUIRRELVM v) { - return sq_arrayreverse(v,-1); + return SQ_SUCCEEDED(sq_arrayreverse(v,-1)) ? 1 : SQ_ERROR; } static SQInteger array_pop(HSQUIRRELVM v) @@ -555,7 +582,8 @@ static SQInteger array_insert(HSQUIRRELVM v) SQObject &val=stack_get(v,3); if(!_array(o)->Insert(tointeger(idx),val)) return sq_throwerror(v,_SC("index out of range")); - return 0; + sq_pop(v,2); + return 1; } static SQInteger array_remove(HSQUIRRELVM v) @@ -585,7 +613,8 @@ static SQInteger array_resize(HSQUIRRELVM v) if(sq_gettop(v) > 2) fill = stack_get(v, 3); _array(o)->Resize(sz,fill); - return 0; + sq_settop(v, 1); + return 1; } return sq_throwerror(v, _SC("size must be a number")); } @@ -593,16 +622,36 @@ static SQInteger array_resize(HSQUIRRELVM v) static SQInteger __map_array(SQArray *dest,SQArray *src,HSQUIRRELVM v) { SQObjectPtr temp; SQInteger size = src->Size(); + SQObject &closure = stack_get(v, 2); + v->Push(closure); + + SQInteger nArgs; + if(sq_type(closure) == OT_CLOSURE) { + nArgs = _closure(closure)->_function->_nparameters; + } + else if (sq_type(closure) == OT_NATIVECLOSURE) { + SQInteger nParamsCheck = _nativeclosure(closure)->_nparamscheck; + if (nParamsCheck > 0) + nArgs = nParamsCheck; + else // push all params when there is no check or only minimal count set + nArgs = 4; + } + for(SQInteger n = 0; n < size; n++) { src->Get(n,temp); v->Push(src); v->Push(temp); - if(SQ_FAILED(sq_call(v,2,SQTrue,SQFalse))) { + if (nArgs >= 3) + v->Push(SQObjectPtr(n)); + if (nArgs >= 4) + v->Push(src); + if(SQ_FAILED(sq_call(v,nArgs,SQTrue,SQFalse))) { return SQ_ERROR; } dest->Set(n,v->GetUp(-1)); v->Pop(); } + v->Pop(); return 0; } @@ -622,7 +671,8 @@ static SQInteger array_apply(HSQUIRRELVM v) SQObject &o = stack_get(v,1); if(SQ_FAILED(__map_array(_array(o),_array(o),v))) return SQ_ERROR; - return 0; + sq_pop(v,1); + return 1; } static SQInteger array_reduce(HSQUIRRELVM v) @@ -630,14 +680,21 @@ static SQInteger array_reduce(HSQUIRRELVM v) SQObject &o = stack_get(v,1); SQArray *a = _array(o); SQInteger size = a->Size(); - if(size == 0) { + SQObjectPtr res; + SQInteger iterStart; + if (sq_gettop(v)>2) { + res = stack_get(v,3); + iterStart = 0; + } else if (size==0) { return 0; + } else { + a->Get(0,res); + iterStart = 1; } - SQObjectPtr res; - a->Get(0,res); - if(size > 1) { + if (size > iterStart) { SQObjectPtr other; - for(SQInteger n = 1; n < size; n++) { + v->Push(stack_get(v,2)); + for (SQInteger n = iterStart; n < size; n++) { a->Get(n,other); v->Push(o); v->Push(res); @@ -648,6 +705,7 @@ static SQInteger array_reduce(HSQUIRRELVM v) res = v->GetUp(-1); v->Pop(); } + v->Pop(); } v->Push(res); return 1; @@ -789,7 +847,8 @@ static SQInteger array_sort(HSQUIRRELVM v) return SQ_ERROR; } - return 0; + sq_settop(v,1); + return 1; } static SQInteger array_slice(HSQUIRRELVM v) @@ -832,7 +891,7 @@ const SQRegFunction SQSharedState::_array_default_delegate_funcz[]={ {_SC("clear"),obj_clear,1, _SC(".")}, {_SC("map"),array_map,2, _SC("ac")}, {_SC("apply"),array_apply,2, _SC("ac")}, - {_SC("reduce"),array_reduce,2, _SC("ac")}, + {_SC("reduce"),array_reduce,-2, _SC("ac.")}, {_SC("filter"),array_filter,2, _SC("ac")}, {_SC("find"),array_find,2, _SC("a.")}, {NULL,(SQFUNCTION)0,0,NULL} diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqcompiler.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqcompiler.cpp index 04d7e6ec27e..095edd71c69 100644 --- a/src/modules/app_sqlang/squirrel/squirrel/sqcompiler.cpp +++ b/src/modules/app_sqlang/squirrel/squirrel/sqcompiler.cpp @@ -443,8 +443,8 @@ class SQCompiler Expression(); SQInteger 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->SetInstructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos); + _fs->SetInstructionParam(jzpos, 1, endfirstexp - jzpos + 1); _fs->SnoozeOpt(); } break; @@ -482,7 +482,7 @@ class SQCompiler SQInteger second_exp = _fs->PopTarget(); if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); _fs->SnoozeOpt(); - _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos)); + _fs->SetInstructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos)); _es.etype = EXPR; break; }else return; @@ -502,7 +502,7 @@ class SQCompiler SQInteger second_exp = _fs->PopTarget(); if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); _fs->SnoozeOpt(); - _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos)); + _fs->SetInstructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos)); _es.etype = EXPR; break; } @@ -635,7 +635,7 @@ class SQCompiler } break; case _SC('['): - if(_lex._prevtoken == _SC('\n')) Error(_SC("cannot brake deref/or comma needed after [exp]=exp slot declaration")); + if(_lex._prevtoken == _SC('\n')) Error(_SC("cannot break deref/or comma needed after [exp]=exp slot declaration")); Lex(); Expression(); Expect(_SC(']')); pos = -1; if(_es.etype==BASE) { @@ -834,7 +834,7 @@ class SQCompiler _fs->AddInstruction(_OP_APPENDARRAY, array, val, AAT_STACK); key++; } - _fs->SetIntructionParam(apos, 1, key); + _fs->SetInstructionParam(apos, 1, key); Lex(); } break; @@ -940,6 +940,30 @@ class SQCompiler SQInteger stackbase = _fs->PopTarget(); SQInteger closure = _fs->PopTarget(); _fs->AddInstruction(_OP_CALL, _fs->PushTarget(), closure, stackbase, nargs); + if (_token == '{') + { + SQInteger retval = _fs->TopTarget(); + SQInteger nkeys = 0; + Lex(); + while (_token != '}') { + switch (_token) { + 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(); + break; + } + if (_token == ',') Lex(); + nkeys++; + SQInteger val = _fs->PopTarget(); + SQInteger key = _fs->PopTarget(); + _fs->AddInstruction(_OP_SET, 0xFF, retval, key, val); + } + Lex(); + } } void ParseTableOrClass(SQInteger separator,SQInteger terminator) { @@ -1002,7 +1026,7 @@ class SQCompiler } } if(separator == _SC(',')) //hack recognizes a table from the separator - _fs->SetIntructionParam(tpos, 1, nkeys); + _fs->SetInstructionParam(tpos, 1, nkeys); Lex(); } void LocalDeclStatement() @@ -1092,9 +1116,9 @@ class SQCompiler //Statement(); if(_lex._prevtoken != _SC('}')) OptionalSemicolon(); IfBlock(); //END_SCOPE(); - _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos); + _fs->SetInstructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos); } - _fs->SetIntructionParam(jnepos, 1, endifblock - jnepos + (haselse?1:0)); + _fs->SetInstructionParam(jnepos, 1, endifblock - jnepos + (haselse?1:0)); } void WhileStatement() { @@ -1111,7 +1135,7 @@ class SQCompiler END_SCOPE(); _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1); - _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos); + _fs->SetInstructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos); END_BREAKBLE_BLOCK(jmppos); } @@ -1170,7 +1194,7 @@ class SQCompiler _fs->AddInstruction(exp[i]); } _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1, 0); - if(jzpos> 0) _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos); + if(jzpos> 0) _fs->SetInstructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos); END_BREAKBLE_BLOCK(continuetrg); @@ -1211,8 +1235,8 @@ class SQCompiler BEGIN_BREAKBLE_BLOCK() Statement(); _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1); - _fs->SetIntructionParam(foreachpos, 1, _fs->GetCurrentPos() - foreachpos); - _fs->SetIntructionParam(foreachpos + 1, 1, _fs->GetCurrentPos() - foreachpos); + _fs->SetInstructionParam(foreachpos, 1, _fs->GetCurrentPos() - foreachpos); + _fs->SetInstructionParam(foreachpos + 1, 1, _fs->GetCurrentPos() - foreachpos); END_BREAKBLE_BLOCK(foreachpos - 1); //restore the local variable stack(remove index,val and ref idx) _fs->PopTarget(); @@ -1232,7 +1256,7 @@ class SQCompiler if(!bfirst) { _fs->AddInstruction(_OP_JMP, 0, 0); skipcondjmp = _fs->GetCurrentPos(); - _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp); + _fs->SetInstructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp); } //condition Lex(); Expression(); Expect(_SC(':')); @@ -1250,7 +1274,7 @@ class SQCompiler //end condition if(skipcondjmp != -1) { - _fs->SetIntructionParam(skipcondjmp, 1, (_fs->GetCurrentPos() - skipcondjmp)); + _fs->SetInstructionParam(skipcondjmp, 1, (_fs->GetCurrentPos() - skipcondjmp)); } tonextcondjmp = _fs->GetCurrentPos(); BEGIN_SCOPE(); @@ -1259,7 +1283,7 @@ class SQCompiler bfirst = false; } if(tonextcondjmp != -1) - _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp); + _fs->SetInstructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp); if(_token == TK_DEFAULT) { Lex(); Expect(_SC(':')); BEGIN_SCOPE(); @@ -1403,14 +1427,14 @@ class SQCompiler if(_fs->_continuetargets.size()) _fs->_continuetargets.top()--; _fs->AddInstruction(_OP_JMP, 0, 0); SQInteger jmppos = _fs->GetCurrentPos(); - _fs->SetIntructionParam(trappos, 1, (_fs->GetCurrentPos() - trappos)); + _fs->SetInstructionParam(trappos, 1, (_fs->GetCurrentPos() - trappos)); Expect(TK_CATCH); Expect(_SC('(')); exid = Expect(TK_IDENTIFIER); Expect(_SC(')')); { BEGIN_SCOPE(); SQInteger ex_target = _fs->PushLocalVariable(exid); - _fs->SetIntructionParam(trappos, 0, ex_target); + _fs->SetInstructionParam(trappos, 0, ex_target); Statement(); - _fs->SetIntructionParams(jmppos, 0, (_fs->GetCurrentPos() - jmppos), 0); + _fs->SetInstructionParams(jmppos, 0, (_fs->GetCurrentPos() - jmppos), 0); END_SCOPE(); } } @@ -1548,7 +1572,7 @@ class SQCompiler SQInteger pos = funcstate->_unresolvedbreaks.back(); funcstate->_unresolvedbreaks.pop_back(); //set the jmp instruction - funcstate->SetIntructionParams(pos, 0, funcstate->GetCurrentPos() - pos, 0); + funcstate->SetInstructionParams(pos, 0, funcstate->GetCurrentPos() - pos, 0); ntoresolve--; } } @@ -1558,7 +1582,7 @@ class SQCompiler SQInteger pos = funcstate->_unresolvedcontinues.back(); funcstate->_unresolvedcontinues.pop_back(); //set the jmp instruction - funcstate->SetIntructionParams(pos, 0, targetpos - pos, 0); + funcstate->SetInstructionParams(pos, 0, targetpos - pos, 0); ntoresolve--; } } diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.cpp index 6d633c7f720..779b40df420 100644 --- a/src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.cpp +++ b/src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.cpp @@ -238,7 +238,7 @@ SQInteger SQFuncState::GetConstant(const SQObject &cons) return _integer(val); } -void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3) +void SQFuncState::SetInstructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3) { _instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&arg0); _instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&arg1); @@ -246,7 +246,7 @@ void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg _instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&arg3); } -void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val) +void SQFuncState::SetInstructionParam(SQInteger pos,SQInteger arg,SQInteger val) { switch(arg){ case 0:_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&val);break; @@ -481,7 +481,6 @@ void SQFuncState::AddInstruction(SQInstruction &i) 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; @@ -493,7 +492,6 @@ void SQFuncState::AddInstruction(SQInstruction &i) 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; @@ -511,7 +509,6 @@ void SQFuncState::AddInstruction(SQInstruction &i) if(aat != -1 && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){ pi.op = _OP_APPENDARRAY; pi._arg0 = i._arg0; - pi._arg1 = pi._arg1; pi._arg2 = (unsigned char)aat; pi._arg3 = MAX_FUNC_STACKSIZE; return; @@ -553,7 +550,6 @@ void SQFuncState::AddInstruction(SQInstruction &i) { pi.op = i.op; pi._arg0 = i._arg0; - pi._arg1 = pi._arg1; pi._arg2 = i._arg2; pi._arg3 = MAX_FUNC_STACKSIZE; return; diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.h b/src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.h index a693d13a91f..130aa54ff6b 100644 --- a/src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.h +++ b/src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.h @@ -16,8 +16,8 @@ struct SQFuncState void PopChildState(); 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);} void AddInstruction(SQInstruction &i); - void SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2=0,SQInteger arg3=0); - void SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val); + void SetInstructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2=0,SQInteger arg3=0); + void SetInstructionParam(SQInteger pos,SQInteger arg,SQInteger val); SQInstruction &GetInstruction(SQInteger pos){return _instructions[pos];} void PopInstructions(SQInteger size){for(SQInteger i=0;iRaise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated")); @@ -299,7 +299,7 @@ bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUnsignedInteger return SafeWrite(v,write,up,&tag,sizeof(tag)); } -bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUnsignedInteger32 tag) +bool CheckTag(HSQUIRRELVM v,SQREADFUNC read,SQUserPointer up,SQUnsignedInteger32 tag) { SQUnsignedInteger32 t; _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t))); diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqvm.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqvm.cpp index 3cb643a1d88..b39be72a779 100644 --- a/src/modules/app_sqlang/squirrel/squirrel/sqvm.cpp +++ b/src/modules/app_sqlang/squirrel/squirrel/sqvm.cpp @@ -296,6 +296,9 @@ bool SQVM::ToString(const SQObjectPtr &o,SQObjectPtr &res) case OT_BOOL: scsprintf(_sp(sq_rsl(6)),sq_rsl(6),_integer(o)?_SC("true"):_SC("false")); break; + case OT_NULL: + scsprintf(_sp(sq_rsl(5)),sq_rsl(5),_SC("null")); + break; case OT_TABLE: case OT_USERDATA: case OT_INSTANCE: @@ -383,7 +386,8 @@ bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger args,SQIntege { paramssize--; if (nargs < paramssize) { - Raise_Error(_SC("wrong number of parameters")); + Raise_Error(_SC("wrong number of parameters (%d passed, at least %d required)"), + (int)nargs, (int)paramssize); return false; } @@ -409,7 +413,8 @@ bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger args,SQIntege } } else { - Raise_Error(_SC("wrong number of parameters")); + Raise_Error(_SC("wrong number of parameters (%d passed, %d required)"), + (int)nargs, (int)paramssize); return false; } } @@ -639,8 +644,14 @@ bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes bool SQVM::IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res) { - if(sq_type(o1) == sq_type(o2)) { - res = (_rawval(o1) == _rawval(o2)); + SQObjectType t1 = sq_type(o1), t2 = sq_type(o2); + if(t1 == t2) { + if (t1 == OT_FLOAT) { + res = (_float(o1) == _float(o2)); + } + else { + res = (_rawval(o1) == _rawval(o2)); + } } else { if(sq_isnumeric(o1) && sq_isnumeric(o2)) { @@ -998,8 +1009,9 @@ bool SQVM::Execute(SQObjectPtr &closure, SQInteger nargs, SQInteger stackbase,SQ case _OP_YIELD:{ if(ci->_generator) { if(sarg1 != MAX_FUNC_STACKSIZE) temp_reg = STK(arg1); + if (_openouters) CloseOuters(&_stack._vals[_stackbase]); _GUARD(ci->_generator->Yield(this,arg2)); - traps -= ci->_etraps; + traps -= ci->_etraps; if(sarg1 != MAX_FUNC_STACKSIZE) _Swap(STK(arg1),temp_reg);//STK(arg1) = temp_reg; } else { Raise_Error(_SC("trying to yield a '%s',only genenerator can be yielded"), GetTypeName(ci->_generator)); SQ_THROW();} @@ -1358,7 +1370,7 @@ bool SQVM::Set(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr return false; } return true; - case OT_USERDATA: break; // must fall back + case OT_USERDATA: break; // must fall back default: Raise_Error(_SC("trying to set '%s'"),GetTypeName(self)); return false; @@ -1763,7 +1775,7 @@ void SQVM::dumpstack(SQInteger stackbase,bool dumpall) 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; - case OT_WEAKREF: scprintf(_SC("WEAKERF %p"),_weakref(obj));break; + case OT_WEAKREF: scprintf(_SC("WEAKREF %p"),_weakref(obj));break; default: assert(0); break;