1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-06-21 09:37:13 +02:00

Dumped the old implementation. Started with a more simple approach.

This commit is contained in:
Sandu Liviu Catalin
2016-02-21 00:25:00 +02:00
parent 96ded94026
commit 06e598acfb
293 changed files with 37439 additions and 92564 deletions
bin
cbp
config
external
include
source
Base
Command.cppCommand.hppCommon.hppConstants.cppCore.cppCore.hppDebug.cppDebug.hppEntity.cppEntity.hpp
Entity
Event
Iterators.cppIterators.hpp
Library
Logger.cppLogger.hppMain.cppMisc.cpp
Misc
Register.cppRegister.hppSignal.hppSqBase.hpp
Utility

@ -13,7 +13,7 @@
#include "sqfuncstate.h"
#include "sqclass.h"
bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPtr **o)
static bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPtr **o)
{
*o = &stack_get(v,idx);
if(type(**o) != type){
@ -34,7 +34,8 @@ bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPt
SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type)
{
scsprintf(_ss(v)->GetScratchPad(100), 100 *sizeof(SQChar), _SC("unexpected type %s"), IdType2Name(type));
SQUnsignedInteger buf_size = 100 *sizeof(SQChar);
scsprintf(_ss(v)->GetScratchPad(buf_size), buf_size, _SC("unexpected type %s"), IdType2Name(type));
return sq_throwerror(v, _ss(v)->GetScratchPad(-1));
}
@ -179,6 +180,12 @@ SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po)
#endif
}
SQUnsignedInteger sq_getvmrefcount(HSQUIRRELVM v, const HSQOBJECT *po)
{
if (!ISREFCOUNTED(type(*po))) return 0;
return po->_unVal.pRefCounted->_uiRef;
}
const SQChar *sq_objtostring(const HSQOBJECT *o)
{
if(sq_type(*o) == OT_STRING) {
@ -251,6 +258,11 @@ void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p)
v->Push(p);
}
void sq_pushthread(HSQUIRRELVM v, HSQUIRRELVM thread)
{
v->Push(thread);
}
SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size)
{
SQUserData *ud = SQUserData::Create(_ss(v), size + SQ_ALIGNMENT);
@ -443,6 +455,7 @@ SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx)
return sq_throwerror(v,_SC("the target is not a closure"));
SQObjectPtr &env = stack_get(v,-1);
if(!sq_istable(env) &&
!sq_isarray(env) &&
!sq_isclass(env) &&
!sq_isinstance(env))
return sq_throwerror(v,_SC("invalid environment"));
@ -880,29 +893,30 @@ SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx)
SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx)
{
SQObjectPtr &self = stack_get(v, idx);
if(type(v->GetUp(-2)) == OT_NULL) {
SQObjectPtr &key = v->GetUp(-2);
if(type(key) == OT_NULL) {
v->Pop(2);
return sq_throwerror(v, _SC("null key"));
}
switch(type(self)) {
case OT_TABLE:
_table(self)->NewSlot(v->GetUp(-2), v->GetUp(-1));
_table(self)->NewSlot(key, v->GetUp(-1));
v->Pop(2);
return SQ_OK;
break;
case OT_CLASS:
_class(self)->NewSlot(_ss(v), v->GetUp(-2), v->GetUp(-1),false);
_class(self)->NewSlot(_ss(v), key, v->GetUp(-1),false);
v->Pop(2);
return SQ_OK;
break;
case OT_INSTANCE:
if(_instance(self)->Set(v->GetUp(-2), v->GetUp(-1))) {
if(_instance(self)->Set(key, v->GetUp(-1))) {
v->Pop(2);
return SQ_OK;
}
break;
case OT_ARRAY:
if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) {
if(v->Set(self, key, v->GetUp(-1),false)) {
v->Pop(2);
return SQ_OK;
}
@ -918,8 +932,9 @@ SQRESULT sq_newmember(HSQUIRRELVM v,SQInteger idx,SQBool bstatic)
{
SQObjectPtr &self = stack_get(v, idx);
if(type(self) != OT_CLASS) return sq_throwerror(v, _SC("new member only works with classes"));
if(type(v->GetUp(-3)) == OT_NULL) return sq_throwerror(v, _SC("null key"));
if(!v->NewSlotA(self,v->GetUp(-3),v->GetUp(-2),v->GetUp(-1),bstatic?true:false,false))
SQObjectPtr &key = v->GetUp(-3);
if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null key"));
if(!v->NewSlotA(self,key,v->GetUp(-2),v->GetUp(-1),bstatic?true:false,false))
return SQ_ERROR;
return SQ_OK;
}
@ -928,8 +943,9 @@ SQRESULT sq_rawnewmember(HSQUIRRELVM v,SQInteger idx,SQBool bstatic)
{
SQObjectPtr &self = stack_get(v, idx);
if(type(self) != OT_CLASS) return sq_throwerror(v, _SC("new member only works with classes"));
if(type(v->GetUp(-3)) == OT_NULL) return sq_throwerror(v, _SC("null key"));
if(!v->NewSlotA(self,v->GetUp(-3),v->GetUp(-2),v->GetUp(-1),bstatic?true:false,true))
SQObjectPtr &key = v->GetUp(-3);
if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null key"));
if(!v->NewSlotA(self,key,v->GetUp(-2),v->GetUp(-1),bstatic?true:false,true))
return SQ_ERROR;
return SQ_OK;
}
@ -999,7 +1015,8 @@ SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx)
SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx)
{
SQObjectPtr &self=stack_get(v,idx);
if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,DONT_FALL_BACK))
SQObjectPtr &obj = v->GetUp(-1);
if(v->Get(self,obj,obj,false,DONT_FALL_BACK))
return SQ_OK;
v->Pop();
return SQ_ERROR;
@ -1008,23 +1025,23 @@ SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx)
SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx)
{
SQObjectPtr &self=stack_get(v,idx);
SQObjectPtr &obj = v->GetUp(-1);
switch(type(self)) {
case OT_TABLE:
if(_table(self)->Get(v->GetUp(-1),v->GetUp(-1)))
if(_table(self)->Get(obj,obj))
return SQ_OK;
break;
case OT_CLASS:
if(_class(self)->Get(v->GetUp(-1),v->GetUp(-1)))
if(_class(self)->Get(obj,obj))
return SQ_OK;
break;
case OT_INSTANCE:
if(_instance(self)->Get(v->GetUp(-1),v->GetUp(-1)))
if(_instance(self)->Get(obj,obj))
return SQ_OK;
break;
case OT_ARRAY:{
SQObjectPtr& key = v->GetUp(-1);
if(sq_isnumeric(key)){
if(_array(self)->Get(tointeger(key),v->GetUp(-1))) {
if(sq_isnumeric(obj)){
if(_array(self)->Get(tointeger(obj),obj)) {
return SQ_OK;
}
}
@ -1037,7 +1054,7 @@ SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx)
default:
v->Pop();
return sq_throwerror(v,_SC("rawget works only on array/table/instance and class"));
}
}
v->Pop();
return sq_throwerror(v,_SC("the index doesn't exist"));
}
@ -1120,9 +1137,10 @@ SQRESULT sq_reservestack(HSQUIRRELVM v,SQInteger nsize)
SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror)
{
if(type(v->GetUp(-1))==OT_GENERATOR){
if (type(v->GetUp(-1)) == OT_GENERATOR)
{
v->PushNull(); //retval
if(!v->Execute(v->GetUp(-2),0,v->_top,v->GetUp(-1),raiseerror,SQVM::ET_RESUME_GENERATOR))
if (!v->Execute(v->GetUp(-2), 0, v->_top, v->GetUp(-1), raiseerror, SQVM::ET_RESUME_GENERATOR))
{v->Raise_Error(v->_lasterror); return SQ_ERROR;}
if(!retval)
v->Pop();
@ -1192,6 +1210,20 @@ void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook)
}
}
SQRELEASEHOOK sq_getreleasehook(HSQUIRRELVM v,SQInteger idx)
{
if(sq_gettop(v) >= 1){
SQObjectPtr &ud=stack_get(v,idx);
switch( type(ud) ) {
case OT_USERDATA: return _userdata(ud)->_hook; break;
case OT_INSTANCE: return _instance(ud)->_hook; break;
case OT_CLASS: return _class(ud)->_hook; break;
default: break; //shutup compiler
}
}
return NULL;
}
void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f)
{
_ss(v)->_compilererrorhandler = f;

@ -13,7 +13,7 @@
#include <stdarg.h>
#include <ctype.h>
bool str2num(const SQChar *s,SQObjectPtr &res,SQInteger base)
static bool str2num(const SQChar *s,SQObjectPtr &res,SQInteger base)
{
SQChar *end;
const SQChar *e = s;
@ -166,9 +166,11 @@ static SQInteger get_slice_params(HSQUIRRELVM v,SQInteger &sidx,SQInteger &eidx,
sidx=0;
eidx=0;
o=stack_get(v,1);
SQObjectPtr &start=stack_get(v,2);
if(type(start)!=OT_NULL && sq_isnumeric(start)){
sidx=tointeger(start);
if(top>1){
SQObjectPtr &start=stack_get(v,2);
if(type(start)!=OT_NULL && sq_isnumeric(start)){
sidx=tointeger(start);
}
}
if(top>2){
SQObjectPtr &end=stack_get(v,3);
@ -653,7 +655,7 @@ static SQInteger array_find(HSQUIRRELVM v)
}
bool _sort_compare(HSQUIRRELVM v,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret)
static bool _sort_compare(HSQUIRRELVM v,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret)
{
if(func < 0) {
if(!v->ObjCmp(a,b,ret)) return false;
@ -679,7 +681,7 @@ bool _sort_compare(HSQUIRRELVM v,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQ
return true;
}
bool _hsort_sift_down(HSQUIRRELVM v,SQArray *arr, SQInteger root, SQInteger bottom, SQInteger func)
static bool _hsort_sift_down(HSQUIRRELVM v,SQArray *arr, SQInteger root, SQInteger bottom, SQInteger func)
{
SQInteger maxChild;
SQInteger done = 0;
@ -719,7 +721,7 @@ bool _hsort_sift_down(HSQUIRRELVM v,SQArray *arr, SQInteger root, SQInteger bott
return true;
}
bool _hsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger l, SQInteger r,SQInteger func)
static bool _hsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger l, SQInteger r,SQInteger func)
{
SQArray *a = _array(arr);
SQInteger i;
@ -758,7 +760,7 @@ static SQInteger array_slice(HSQUIRRELVM v)
if(sidx < 0)sidx = alen + sidx;
if(eidx < 0)eidx = alen + eidx;
if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes"));
if(eidx > alen)return sq_throwerror(v,_SC("slice out of range"));
if(eidx > alen || sidx < 0)return sq_throwerror(v, _SC("slice out of range"));
SQArray *arr=SQArray::Create(_ss(v),eidx-sidx);
SQObjectPtr t;
SQInteger count=0;
@ -805,7 +807,7 @@ static SQInteger string_slice(HSQUIRRELVM v)
if(sidx < 0)sidx = slen + sidx;
if(eidx < 0)eidx = slen + eidx;
if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes"));
if(eidx > slen) return sq_throwerror(v,_SC("slice out of range"));
if(eidx > slen || sidx < 0) return sq_throwerror(v, _SC("slice out of range"));
v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx));
return 1;
}
@ -829,13 +831,21 @@ static SQInteger string_find(HSQUIRRELVM v)
}
#define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \
{ \
SQObject str=stack_get(v,1); \
{\
SQInteger sidx,eidx; \
SQObjectPtr str; \
if(SQ_FAILED(get_slice_params(v,sidx,eidx,str)))return -1; \
SQInteger slen = _string(str)->_len; \
if(sidx < 0)sidx = slen + sidx; \
if(eidx < 0)eidx = slen + eidx; \
if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes")); \
if(eidx > slen || sidx < 0) return sq_throwerror(v,_SC("slice out of range")); \
SQInteger len=_string(str)->_len; \
const SQChar *sThis=_stringval(str); \
SQChar *sNew=(_ss(v)->GetScratchPad(rsl(len))); \
for(SQInteger i=0;i<len;i++) sNew[i]=func(sThis[i]); \
v->Push(SQString::Create(_ss(v),sNew,len)); \
const SQChar *sthis=_stringval(str); \
SQChar *snew=(_ss(v)->GetScratchPad(sq_rsl(len))); \
memcpy(snew,sthis,sq_rsl(len));\
for(SQInteger i=sidx;i<eidx;i++) snew[i] = func(sthis[i]); \
v->Push(SQString::Create(_ss(v),snew,len)); \
return 1; \
}
@ -848,10 +858,10 @@ SQRegFunction SQSharedState::_string_default_delegate_funcz[]={
{_SC("tointeger"),default_delegate_tointeger,-1, _SC("sn")},
{_SC("tofloat"),default_delegate_tofloat,1, _SC("s")},
{_SC("tostring"),default_delegate_tostring,1, _SC(".")},
{_SC("slice"),string_slice,-1, _SC(" s n n")},
{_SC("find"),string_find,-2, _SC("s s n ")},
{_SC("tolower"),string_tolower,1, _SC("s")},
{_SC("toupper"),string_toupper,1, _SC("s")},
{_SC("slice"),string_slice,-1, _SC("s n n")},
{_SC("find"),string_find,-2, _SC("s s n")},
{_SC("tolower"),string_tolower,-1, _SC("s n n")},
{_SC("toupper"),string_toupper,-1, _SC("s n n")},
{_SC("weakref"),obj_delegate_weakref,1, NULL },
{0,0}
};
@ -1032,7 +1042,7 @@ static SQInteger thread_wakeup(HSQUIRRELVM v)
}
}
SQInteger wakeupret = sq_gettop(v)>1?1:0;
SQInteger wakeupret = sq_gettop(v)>1?SQTrue:SQFalse;
if(wakeupret) {
sq_move(thread,v,2);
}
@ -1051,6 +1061,47 @@ static SQInteger thread_wakeup(HSQUIRRELVM v)
return sq_throwerror(v,_SC("wrong parameter"));
}
static SQInteger thread_wakeupthrow(HSQUIRRELVM v)
{
SQObjectPtr o = stack_get(v,1);
if(type(o) == OT_THREAD) {
SQVM *thread = _thread(o);
SQInteger state = sq_getvmstate(thread);
if(state != SQ_VMSTATE_SUSPENDED) {
switch(state) {
case SQ_VMSTATE_IDLE:
return sq_throwerror(v,_SC("cannot wakeup a idle thread"));
break;
case SQ_VMSTATE_RUNNING:
return sq_throwerror(v,_SC("cannot wakeup a running thread"));
break;
}
}
sq_move(thread,v,2);
sq_throwobject(thread);
SQBool rethrow_error = SQTrue;
if(sq_gettop(v) > 2) {
sq_getbool(v,3,&rethrow_error);
}
if(SQ_SUCCEEDED(sq_wakeupvm(thread,SQFalse,SQTrue,SQTrue,SQTrue))) {
sq_move(v,thread,-1);
sq_pop(thread,1); //pop retval
if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) {
sq_settop(thread,1); //pop roottable
}
return 1;
}
sq_settop(thread,1);
if(rethrow_error) {
v->_lasterror = thread->_lasterror;
return SQ_ERROR;
}
return SQ_OK;
}
return sq_throwerror(v,_SC("wrong parameter"));
}
static SQInteger thread_getstatus(HSQUIRRELVM v)
{
SQObjectPtr &o = stack_get(v,1);
@ -1106,6 +1157,7 @@ static SQInteger thread_getstackinfos(HSQUIRRELVM v)
SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = {
{_SC("call"), thread_call, -1, _SC("v")},
{_SC("wakeup"), thread_wakeup, -1, _SC("v")},
{_SC("wakeupthrow"), thread_wakeupthrow, -2, _SC("v.b")},
{_SC("getstatus"), thread_getstatus, 1, _SC("v")},
{_SC("weakref"),obj_delegate_weakref,1, NULL },
{_SC("getstackinfos"),thread_getstackinfos,2, _SC("vn")},

@ -157,7 +157,7 @@ public:
void MoveIfCurrentTargetIsLocal() {
SQInteger trg = _fs->TopTarget();
if(_fs->IsLocal(trg)) {
trg = _fs->PopTarget(); //no pops the target and move it
trg = _fs->PopTarget(); //pops the target and moves it
_fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), trg);
}
}
@ -338,6 +338,7 @@ public:
_fs->PushTarget(p1);
//EmitCompArithLocal(tok, p1, p1, p2);
_fs->AddInstruction(ChooseArithOpByToken(tok),p1, p2, p1, 0);
_fs->SnoozeOpt();
}
break;
case OBJECT:
@ -356,7 +357,9 @@ public:
SQInteger tmp = _fs->PushTarget();
_fs->AddInstruction(_OP_GETOUTER, tmp, pos);
_fs->AddInstruction(ChooseArithOpByToken(tok), tmp, val, tmp, 0);
_fs->AddInstruction(_OP_SETOUTER, tmp, pos, tmp);
_fs->PopTarget();
_fs->PopTarget();
_fs->AddInstruction(_OP_SETOUTER, _fs->PushTarget(), pos, tmp);
}
break;
}
@ -656,6 +659,7 @@ public:
case EXPR: Error(_SC("can't '++' or '--' an expression")); break;
case OBJECT:
case BASE:
if(_es.donot_get == true) { Error(_SC("can't '++' or '--' an expression")); break; } //mmh dor this make sense?
Emit2ArgsOP(_OP_PINC, diff);
break;
case LOCAL: {
@ -706,7 +710,7 @@ public:
}
SQInteger Factor()
{
_es.etype = EXPR;
//_es.etype = EXPR;
switch(_token)
{
case TK_STRING_LITERAL:
@ -864,6 +868,7 @@ public:
case TK___FILE__: _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_sourcename)); Lex(); break;
default: Error(_SC("expression expected"));
}
_es.etype = EXPR;
return -1;
}
void EmitLoadConstInt(SQInteger value,SQInteger target)
@ -871,7 +876,7 @@ public:
if(target < 0) {
target = _fs->PushTarget();
}
if((value & (~((SQInteger)0xFFFFFFFF))) == 0) { //does it fit in 32 bits?
if(value <= INT_MAX && value > INT_MIN) { //does it fit in 32 bits?
_fs->AddInstruction(_OP_LOADINT, target,value);
}
else {
@ -900,8 +905,13 @@ public:
{
switch(_token) {
case _SC('='): case _SC('('): case TK_NEWSLOT: case TK_MODEQ: case TK_MULEQ:
case TK_DIVEQ: case TK_MINUSEQ: case TK_PLUSEQ: case TK_PLUSPLUS: case TK_MINUSMINUS:
case TK_DIVEQ: case TK_MINUSEQ: case TK_PLUSEQ:
return false;
case TK_PLUSPLUS: case TK_MINUSMINUS:
if (!IsEndOfStatement()) {
return false;
}
break;
}
return (!_es.donot_get || ( _es.donot_get && (_token == _SC('.') || _token == _SC('['))));
}
@ -1017,6 +1027,28 @@ public:
if(_token == _SC(',')) Lex(); else break;
} while(1);
}
void IfBlock()
{
if (_token == _SC('{'))
{
BEGIN_SCOPE();
Lex();
Statements();
Expect(_SC('}'));
if (true) {
END_SCOPE();
}
else {
END_SCOPE_NO_CLOSE();
}
}
else {
//BEGIN_SCOPE();
Statement();
if (_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon();
//END_SCOPE();
}
}
void IfStatement()
{
SQInteger jmppos;
@ -1024,22 +1056,33 @@ public:
Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
_fs->AddInstruction(_OP_JZ, _fs->PopTarget());
SQInteger jnepos = _fs->GetCurrentPos();
BEGIN_SCOPE();
Statement();
IfBlock();
//
if(_token != _SC('}') && _token != TK_ELSE) OptionalSemicolon();
/*static int n = 0;
if (_token != _SC('}') && _token != TK_ELSE) {
printf("IF %d-----------------------!!!!!!!!!\n", n);
if (n == 5)
{
printf("asd");
}
n++;
//OptionalSemicolon();
}*/
END_SCOPE();
SQInteger endifblock = _fs->GetCurrentPos();
if(_token == TK_ELSE){
haselse = true;
BEGIN_SCOPE();
//BEGIN_SCOPE();
_fs->AddInstruction(_OP_JMP);
jmppos = _fs->GetCurrentPos();
Lex();
Statement(); if(_lex._prevtoken != _SC('}')) OptionalSemicolon();
END_SCOPE();
//Statement(); if(_lex._prevtoken != _SC('}')) OptionalSemicolon();
IfBlock();
//END_SCOPE();
_fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos);
}
_fs->SetIntructionParam(jnepos, 1, endifblock - jnepos + (haselse?1:0));

@ -61,7 +61,7 @@ void SQVM::Raise_Error(const SQChar *s, ...)
va_list vl;
va_start(vl, s);
SQInteger buffersize = (SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2);
scvsprintf(_sp(rsl(buffersize)),buffersize, s, vl);
scvsprintf(_sp(sq_rsl(buffersize)),buffersize, s, vl);
va_end(vl);
_lasterror = SQString::Create(_ss(this),_spval,-1);
}
@ -76,11 +76,11 @@ SQString *SQVM::PrintObjVal(const SQObjectPtr &o)
switch(type(o)) {
case OT_STRING: return _string(o);
case OT_INTEGER:
scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),rsl(NUMBER_MAX_CHAR), _PRINT_INT_FMT, _integer(o));
scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)),sq_rsl(NUMBER_MAX_CHAR), _PRINT_INT_FMT, _integer(o));
return SQString::Create(_ss(this), _spval);
break;
case OT_FLOAT:
scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), rsl(NUMBER_MAX_CHAR), _SC("%.14g"), _float(o));
scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)), sq_rsl(NUMBER_MAX_CHAR), _SC("%.14g"), _float(o));
return SQString::Create(_ss(this), _spval);
break;
default:

@ -73,7 +73,6 @@ SQInstructionDesc g_InstrDesc[]={
{_SC("_OP_NEWSLOTA")},
{_SC("_OP_GETBASE")},
{_SC("_OP_CLOSE")},
{_SC("_OP_JCMP")}
};
#endif
void DumpLiteral(SQObjectPtr &o)

@ -29,7 +29,7 @@ void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,Compile
_errfunc = efunc;
_errtarget = ed;
_sharedstate = ss;
_keywords = SQTable::Create(ss, 26);
_keywords = SQTable::Create(ss, 37);
ADD_KEYWORD(while, TK_WHILE);
ADD_KEYWORD(do, TK_DO);
ADD_KEYWORD(if, TK_IF);

@ -2,8 +2,10 @@
see copyright notice in squirrel.h
*/
#include "sqpcheader.h"
#ifndef SQ_EXCLUDE_DEFAULT_MEMFUNCTIONS
void *sq_vm_malloc(SQUnsignedInteger size){ return malloc(size); }
void *sq_vm_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size){ return realloc(p, size); }
void sq_vm_free(void *p, SQUnsignedInteger size){ free(p); }
#endif

@ -86,6 +86,9 @@ SQWeakRef *SQRefCounted::GetWeakRef(SQObjectType type)
{
if(!_weakref) {
sq_new(_weakref,SQWeakRef);
#if defined(SQUSEDOUBLE) && !defined(_SQ64)
_weakref->_obj._unVal.raw = 0; //clean the whole union on 32 bits with double
#endif
_weakref->_obj._type = type;
_weakref->_obj._unVal.pRefCounted = this;
}
@ -150,6 +153,10 @@ bool SQGenerator::Yield(SQVM *v,SQInteger target)
for(SQInteger i=0;i<_ci._etraps;i++) {
_etraps.push_back(v->_etraps.top());
v->_etraps.pop_back();
// store relative stack base and size in case of resume to other _top
SQExceptionTrap &et = _etraps.back();
et._stackbase -= v->_stackbase;
et._stacksize -= v->_stackbase;
}
_state=eSuspended;
return true;
@ -162,6 +169,7 @@ bool SQGenerator::Resume(SQVM *v,SQObjectPtr &dest)
SQInteger size = _stack.size();
SQInteger target = &dest - &(v->_stack._vals[v->_stackbase]);
assert(target>=0 && target<=255);
SQInteger newbase = v->_top;
if(!v->EnterFrame(v->_top, v->_top + size, false))
return false;
v->ci->_generator = this;
@ -177,6 +185,10 @@ bool SQGenerator::Resume(SQVM *v,SQObjectPtr &dest)
for(SQInteger i=0;i<_ci._etraps;i++) {
v->_etraps.push_back(_etraps.top());
_etraps.pop_back();
SQExceptionTrap &et = v->_etraps.back();
// restore absolute stack base and size
et._stackbase += newbase;
et._stacksize += newbase;
}
SQObject _this = _stack._vals[0];
v->_stack[v->_stackbase] = type(_this) == OT_WEAKREF ? _weakref(_this)->_obj : _this;
@ -305,7 +317,7 @@ bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o
switch(type(o)){
case OT_STRING:
_CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger)));
_CHECK_IO(SafeWrite(v,write,up,_stringval(o),rsl(_string(o)->_len)));
_CHECK_IO(SafeWrite(v,write,up,_stringval(o),sq_rsl(_string(o)->_len)));
break;
case OT_BOOL:
case OT_INTEGER:
@ -330,7 +342,7 @@ bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o)
case OT_STRING:{
SQInteger len;
_CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger)));
_CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(rsl(len)),rsl(len)));
_CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(sq_rsl(len)),sq_rsl(len)));
o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len);
}
break;

@ -99,7 +99,7 @@ enum SQOpcode
_OP_THROW= 0x39,
_OP_NEWSLOTA= 0x3A,
_OP_GETBASE= 0x3B,
_OP_CLOSE= 0x3C,
_OP_CLOSE= 0x3C
};
struct SQInstructionDesc {

@ -6,6 +6,7 @@
#include <crtdbg.h>
#endif
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

@ -596,14 +596,14 @@ SQString *SQStringTable::Add(const SQChar *news,SQInteger len)
SQHash h = newhash&(_numofslots-1);
SQString *s;
for (s = _strings[h]; s; s = s->_next){
if(s->_len == len && (!memcmp(news,s->_val,rsl(len))))
if(s->_len == len && (!memcmp(news,s->_val,sq_rsl(len))))
return s; //found
}
SQString *t = (SQString *)SQ_MALLOC(rsl(len)+sizeof(SQString));
SQString *t = (SQString *)SQ_MALLOC(sq_rsl(len)+sizeof(SQString));
new (t) SQString;
t->_sharedstate = _sharedstate;
memcpy(t->_val,news,rsl(len));
memcpy(t->_val,news,sq_rsl(len));
t->_val[len] = _SC('\0');
t->_len = len;
t->_hash = newhash;
@ -648,7 +648,7 @@ void SQStringTable::Remove(SQString *bs)
_slotused--;
SQInteger slen = s->_len;
s->~SQString();
SQ_FREE(s,sizeof(SQString) + rsl(slen));
SQ_FREE(s,sizeof(SQString) + sq_rsl(slen));
return;
}
prev = s;

@ -130,14 +130,6 @@ private:
#define _instance_ddel _table(_sharedstate->_instance_default_delegate)
#define _weakref_ddel _table(_sharedstate->_weakref_default_delegate)
#ifdef SQUNICODE //rsl REAL STRING LEN
#define rsl(l) ((l)<<WCHAR_SHIFT_MUL)
#else
#define rsl(l) (l)
#endif
//extern SQObjectPtr _null_;
bool CompileTypemask(SQIntVec &res,const SQChar *typemask);

@ -68,12 +68,14 @@ bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,
switch(op) {
case '+': res = i1 + i2; break;
case '-': res = i1 - i2; break;
case '/': if(i2 == 0) { Raise_Error(_SC("division by zero")); return false; }
res = i1 / i2;
case '/': if (i2 == 0) { Raise_Error(_SC("division by zero")); return false; }
else if (i2 == -1 && i1 == INT_MIN) { Raise_Error(_SC("integer overflow")); return false; }
res = i1 / i2;
break;
case '*': res = i1 * i2; break;
case '%': if(i2 == 0) { Raise_Error(_SC("modulo by zero")); return false; }
res = i1 % i2;
case '%': if (i2 == 0) { Raise_Error(_SC("modulo by zero")); return false; }
else if (i2 == -1 && i1 == INT_MIN) { res = 0; break; }
res = i1 % i2;
break;
default: res = 0xDEADBEEF;
}
@ -284,13 +286,13 @@ bool SQVM::ToString(const SQObjectPtr &o,SQObjectPtr &res)
res = o;
return true;
case OT_FLOAT:
scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),rsl(NUMBER_MAX_CHAR),_SC("%g"),_float(o));
scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)),sq_rsl(NUMBER_MAX_CHAR),_SC("%g"),_float(o));
break;
case OT_INTEGER:
scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),rsl(NUMBER_MAX_CHAR),_PRINT_INT_FMT,_integer(o));
scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)),sq_rsl(NUMBER_MAX_CHAR),_PRINT_INT_FMT,_integer(o));
break;
case OT_BOOL:
scsprintf(_sp(rsl(6)),rsl(6),_integer(o)?_SC("true"):_SC("false"));
scsprintf(_sp(sq_rsl(6)),sq_rsl(6),_integer(o)?_SC("true"):_SC("false"));
break;
case OT_TABLE:
case OT_USERDATA:
@ -309,7 +311,7 @@ bool SQVM::ToString(const SQObjectPtr &o,SQObjectPtr &res)
}
}
default:
scsprintf(_sp(rsl(sizeof(void*)+20)),rsl(sizeof(void*)+20),_SC("(%s : 0x%p)"),GetTypeName(o),(void*)_rawval(o));
scsprintf(_sp(sq_rsl((sizeof(void*)*2)+NUMBER_MAX_CHAR)),sq_rsl((sizeof(void*)*2)+NUMBER_MAX_CHAR),_SC("(%s : 0x%p)"),GetTypeName(o),(void*)_rawval(o));
}
res = SQString::Create(_ss(this),_spval);
return true;
@ -322,9 +324,9 @@ bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr &
if(!ToString(str, a)) return false;
if(!ToString(obj, b)) return false;
SQInteger l = _string(a)->_len , ol = _string(b)->_len;
SQChar *s = _sp(rsl(l + ol + 1));
memcpy(s, _stringval(a), rsl(l));
memcpy(s + l, _stringval(b), rsl(ol));
SQChar *s = _sp(sq_rsl(l + ol + 1));
memcpy(s, _stringval(a), sq_rsl(l));
memcpy(s + l, _stringval(b), sq_rsl(ol));
dest = SQString::Create(_ss(this), _spval, l + ol);
return true;
}
@ -485,7 +487,7 @@ bool SQVM::PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObject
bool SQVM::DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix,SQInteger selfidx)
{
SQObjectPtr tmp, tself = self, tkey = key;
if (!Get(tself, tkey, tmp, false, selfidx)) { return false; }
if (!Get(tself, tkey, tmp, 0, selfidx)) { return false; }
_RET_ON_FAIL(ARITH_OP( op , target, tmp, incr))
if (!Set(tself, tkey, target,selfidx)) { return false; }
if (postfix) target = tmp;
@ -539,7 +541,7 @@ bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr
if(CallMetaMethod(closure, MT_NEXTI, 2, itr)) {
o4 = o2 = itr;
if(type(itr) == OT_NULL) _FINISH(exitpos);
if(!Get(o1, itr, o3, false, DONT_FALL_BACK)) {
if(!Get(o1, itr, o3, 0, DONT_FALL_BACK)) {
Raise_Error(_SC("_nexti returned an invalid idx")); // cloud be changed
return false;
}
@ -713,7 +715,7 @@ exception_restore:
#ifndef _SQ64
TARGET = (SQInteger)arg1; continue;
#else
TARGET = (SQInteger)((SQUnsignedInteger32)arg1); continue;
TARGET = (SQInteger)((SQInt32)arg1); continue;
#endif
case _OP_LOADFLOAT: TARGET = *((SQFloat *)&arg1); continue;
case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue;
@ -800,7 +802,7 @@ exception_restore:
case _OP_PREPCALLK: {
SQObjectPtr &key = _i_.op == _OP_PREPCALLK?(ci->_literals)[arg1]:STK(arg1);
SQObjectPtr &o = STK(arg2);
if (!Get(o, key, temp_reg,false,arg2)) {
if (!Get(o, key, temp_reg,0,arg2)) {
SQ_THROW();
}
STK(arg3) = o;
@ -808,7 +810,7 @@ exception_restore:
}
continue;
case _OP_GETK:
if (!Get(STK(arg2), ci->_literals[arg1], temp_reg, false,arg2)) { SQ_THROW();}
if (!Get(STK(arg2), ci->_literals[arg1], temp_reg, 0,arg2)) { SQ_THROW();}
_Swap(TARGET,temp_reg);//TARGET = temp_reg;
continue;
case _OP_MOVE: TARGET = STK(arg1); continue;
@ -822,7 +824,7 @@ exception_restore:
if (arg0 != 0xFF) TARGET = STK(arg3);
continue;
case _OP_GET:
if (!Get(STK(arg1), STK(arg2), temp_reg, false,arg1)) { SQ_THROW(); }
if (!Get(STK(arg1), STK(arg2), temp_reg, 0,arg1)) { SQ_THROW(); }
_Swap(TARGET,temp_reg);//TARGET = temp_reg;
continue;
case _OP_EQ:{
@ -907,7 +909,7 @@ exception_restore:
#ifndef _SQ64
val._unVal.nInteger = (SQInteger)arg1;
#else
val._unVal.nInteger = (SQInteger)((SQUnsignedInteger32)arg1);
val._unVal.nInteger = (SQInteger)((SQInt32)arg1);
#endif
break;
case AAT_FLOAT:
@ -918,7 +920,7 @@ exception_restore:
val._type = OT_BOOL;
val._unVal.nInteger = arg1;
break;
default: assert(0); break;
default: val._type = OT_INTEGER; assert(0); break;
}
_array(STK(arg0))->Append(val); continue;
@ -952,7 +954,7 @@ exception_restore:
} continue;
case _OP_CMP: _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg1),TARGET)) continue;
case _OP_EXISTS: TARGET = Get(STK(arg1), STK(arg2), temp_reg, true, EXISTS_FALL_BACK)?true:false;continue;
case _OP_EXISTS: TARGET = Get(STK(arg1), STK(arg2), temp_reg, GET_FLAG_DO_NOT_RAISE_ERROR | GET_FLAG_RAW, DONT_FALL_BACK) ? true : false; continue;
case _OP_INSTANCEOF:
if(type(STK(arg1)) != OT_CLASS)
{Raise_Error(_SC("cannot apply instanceof between a %s and a %s"),GetTypeName(STK(arg1)),GetTypeName(STK(arg2))); SQ_THROW();}
@ -1198,14 +1200,14 @@ bool SQVM::CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger newb
#define FALLBACK_NO_MATCH 1
#define FALLBACK_ERROR 2
bool SQVM::Get(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw, SQInteger selfidx)
bool SQVM::Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, SQUnsignedInteger getflags, SQInteger selfidx)
{
switch(type(self)){
case OT_TABLE:
if(_table(self)->Get(key,dest))return true;
break;
case OT_ARRAY:
if(sq_isnumeric(key)) { if(_array(self)->Get(tointeger(key),dest)) { return true; } if(selfidx != EXISTS_FALL_BACK) Raise_IdxError(key); return false; }
if (sq_isnumeric(key)) { if (_array(self)->Get(tointeger(key), dest)) { return true; } if ((getflags & GET_FLAG_DO_NOT_RAISE_ERROR) == 0) Raise_IdxError(key); return false; }
break;
case OT_INSTANCE:
if(_instance(self)->Get(key,dest)) return true;
@ -1216,18 +1218,19 @@ bool SQVM::Get(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,
case OT_STRING:
if(sq_isnumeric(key)){
SQInteger n = tointeger(key);
if(abs((int)n) < _string(self)->_len) {
if(n < 0) n = _string(self)->_len - n;
SQInteger len = _string(self)->_len;
if (n < 0) { n += len; }
if (n >= 0 && n < len) {
dest = SQInteger(_stringval(self)[n]);
return true;
}
if(selfidx != EXISTS_FALL_BACK) Raise_IdxError(key);
if ((getflags & GET_FLAG_DO_NOT_RAISE_ERROR) == 0) Raise_IdxError(key);
return false;
}
break;
default:break; //shut up compiler
}
if(!raw) {
if ((getflags & GET_FLAG_RAW) == 0) {
switch(FallBackGet(self,key,dest)) {
case FALLBACK_OK: return true; //okie
case FALLBACK_NO_MATCH: break; //keep falling back
@ -1242,12 +1245,12 @@ bool SQVM::Get(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,
SQWeakRef *w = _closure(ci->_closure)->_root;
if(type(w->_obj) != OT_NULL)
{
if(Get(*((const SQObjectPtr *)&w->_obj),key,dest,false,DONT_FALL_BACK)) return true;
if(Get(*((const SQObjectPtr *)&w->_obj),key,dest,0,DONT_FALL_BACK)) return true;
}
}
//#endif
if(selfidx != EXISTS_FALL_BACK) Raise_IdxError(key);
if ((getflags & GET_FLAG_DO_NOT_RAISE_ERROR) == 0) Raise_IdxError(key);
return false;
}
@ -1278,7 +1281,7 @@ SQInteger SQVM::FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObj
case OT_USERDATA:
//delegation
if(_delegable(self)->_delegate) {
if(Get(SQObjectPtr(_delegable(self)->_delegate),key,dest,false,DONT_FALL_BACK)) return FALLBACK_OK;
if(Get(SQObjectPtr(_delegable(self)->_delegate),key,dest,0,DONT_FALL_BACK)) return FALLBACK_OK;
}
else {
return FALLBACK_NO_MATCH;
@ -1551,7 +1554,8 @@ SQInteger prevstackbase = _stackbase;
SQObjectPtr constr;
SQObjectPtr temp;
CreateClassInstance(_class(closure),outres,constr);
if(type(constr) != OT_NULL) {
SQObjectType ctype = type(constr);
if (ctype == OT_NATIVECLOSURE || ctype == OT_CLOSURE) {
_stack[stackbase] = outres;
return Call(constr,nparams,stackbase,temp,raiseerror);
}
@ -1631,7 +1635,7 @@ bool SQVM::EnterFrame(SQInteger newbase, SQInteger newtop, bool tailcall)
Raise_Error(_SC("stack overflow, cannot resize stack while in a metamethod"));
return false;
}
_stack.resize(_stack.size() + (MIN_STACK_OVERHEAD << 2));
_stack.resize(newtop + (MIN_STACK_OVERHEAD << 2));
RelocateOuters();
}
return true;

@ -9,7 +9,10 @@
#define SQ_SUSPEND_FLAG -666
#define DONT_FALL_BACK 666
#define EXISTS_FALL_BACK -1
//#define EXISTS_FALL_BACK -1
#define GET_FLAG_RAW 0x00000001
#define GET_FLAG_DO_NOT_RAISE_ERROR 0x00000002
//base lib
void sq_base_register(HSQUIRRELVM v);
@ -66,7 +69,7 @@ public:
void CallDebugHook(SQInteger type,SQInteger forcedline=0);
void CallErrorHandler(SQObjectPtr &e);
bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, bool raw, SQInteger selfidx);
bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, SQUnsignedInteger getflags, SQInteger selfidx);
SQInteger FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest);
bool InvokeDefaultDelegate(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest);
bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, SQInteger selfidx);