[DEV] remove sq_type()
This commit is contained in:
parent
b6c6a38844
commit
22c303a587
@ -92,8 +92,8 @@ void rabbit::Class::release() {
|
|||||||
|
|
||||||
bool rabbit::Class::newSlot(rabbit::SharedState *ss,const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val,bool bstatic) {
|
bool rabbit::Class::newSlot(rabbit::SharedState *ss,const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val,bool bstatic) {
|
||||||
rabbit::ObjectPtr temp;
|
rabbit::ObjectPtr temp;
|
||||||
bool belongs_to_static_table = sq_type(val) == rabbit::OT_CLOSURE
|
bool belongs_to_static_table = val.isClosure() == true
|
||||||
|| sq_type(val) == rabbit::OT_NATIVECLOSURE
|
|| val.isNativeClosure() == true
|
||||||
|| bstatic;
|
|| bstatic;
|
||||||
if(_locked && !belongs_to_static_table) {
|
if(_locked && !belongs_to_static_table) {
|
||||||
//the class already has an instance so cannot be modified
|
//the class already has an instance so cannot be modified
|
||||||
@ -106,18 +106,18 @@ bool rabbit::Class::newSlot(rabbit::SharedState *ss,const rabbit::ObjectPtr &key
|
|||||||
}
|
}
|
||||||
if(belongs_to_static_table) {
|
if(belongs_to_static_table) {
|
||||||
int64_t mmidx;
|
int64_t mmidx;
|
||||||
if( ( sq_type(val) == rabbit::OT_CLOSURE
|
if( ( val.isClosure() == true
|
||||||
|| sq_type(val) == rabbit::OT_NATIVECLOSURE )
|
|| val.isNativeClosure() == true )
|
||||||
&& (mmidx = ss->getMetaMethodIdxByName(key)) != -1) {
|
&& (mmidx = ss->getMetaMethodIdxByName(key)) != -1) {
|
||||||
_metamethods[mmidx] = val;
|
_metamethods[mmidx] = val;
|
||||||
} else {
|
} else {
|
||||||
rabbit::ObjectPtr theval = val;
|
rabbit::ObjectPtr theval = val;
|
||||||
if(_base && sq_type(val) == rabbit::OT_CLOSURE) {
|
if(_base && val.isClosure() == true) {
|
||||||
theval = const_cast<rabbit::Closure*>(val.toClosure())->clone();
|
theval = const_cast<rabbit::Closure*>(val.toClosure())->clone();
|
||||||
theval.toClosure()->_base = _base;
|
theval.toClosure()->_base = _base;
|
||||||
__ObjaddRef(_base); //ref for the closure
|
__ObjaddRef(_base); //ref for the closure
|
||||||
}
|
}
|
||||||
if(sq_type(temp) == rabbit::OT_NULL) {
|
if(temp.isNull() == true) {
|
||||||
bool isconstructor;
|
bool isconstructor;
|
||||||
rabbit::VirtualMachine::isEqual(ss->_constructoridx, key, isconstructor);
|
rabbit::VirtualMachine::isEqual(ss->_constructoridx, key, isconstructor);
|
||||||
if(isconstructor) {
|
if(isconstructor) {
|
||||||
|
@ -61,23 +61,23 @@ bool rabbit::CheckTag(rabbit::VirtualMachine* v,SQWRITEFUNC read,rabbit::UserPoi
|
|||||||
|
|
||||||
bool rabbit::WriteObject(rabbit::VirtualMachine* v,rabbit::UserPointer up,SQWRITEFUNC write,rabbit::ObjectPtr &o)
|
bool rabbit::WriteObject(rabbit::VirtualMachine* v,rabbit::UserPointer up,SQWRITEFUNC write,rabbit::ObjectPtr &o)
|
||||||
{
|
{
|
||||||
uint32_t _type = (uint32_t)sq_type(o);
|
uint32_t _type = (uint32_t)o.getType();
|
||||||
_CHECK_IO(SafeWrite(v,write,up,&_type,sizeof(_type)));
|
_CHECK_IO(SafeWrite(v,write,up,&_type,sizeof(_type)));
|
||||||
switch(sq_type(o)){
|
switch(o.getType()){
|
||||||
case rabbit::OT_STRING:
|
case rabbit::OT_STRING:
|
||||||
_CHECK_IO(SafeWrite(v,write,up,&o.toString()->_len,sizeof(int64_t)));
|
_CHECK_IO(SafeWrite(v,write,up,&o.toString()->_len,sizeof(int64_t)));
|
||||||
_CHECK_IO(SafeWrite(v,write,up,_stringval(o),sq_rsl(o.toString()->_len)));
|
_CHECK_IO(SafeWrite(v,write,up,_stringval(o),sq_rsl(o.toString()->_len)));
|
||||||
break;
|
break;
|
||||||
case rabbit::OT_BOOL:
|
case rabbit::OT_BOOL:
|
||||||
case rabbit::OT_INTEGER:
|
case rabbit::OT_INTEGER:
|
||||||
_CHECK_IO(SafeWrite(v,write,up,&o.toInteger(),sizeof(int64_t)));break;
|
_CHECK_IO(SafeWrite(v,write,up,&o.toInteger(),sizeof(int64_t)));break;
|
||||||
case rabbit::OT_FLOAT:
|
case rabbit::OT_FLOAT:
|
||||||
_CHECK_IO(SafeWrite(v,write,up,&o.toFloat(),sizeof(float_t)));break;
|
_CHECK_IO(SafeWrite(v,write,up,&o.toFloat(),sizeof(float_t)));break;
|
||||||
case rabbit::OT_NULL:
|
case rabbit::OT_NULL:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
v->raise_error("cannot serialize a %s",getTypeName(o));
|
v->raise_error("cannot serialize a %s",getTypeName(o));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ public:
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(_raiseerror && _get_shared_state(_vm)->_compilererrorhandler) {
|
if(_raiseerror && _get_shared_state(_vm)->_compilererrorhandler) {
|
||||||
_get_shared_state(_vm)->_compilererrorhandler(_vm, _compilererror, sq_type(_sourcename) == rabbit::OT_STRING?_stringval(_sourcename):"unknown",
|
_get_shared_state(_vm)->_compilererrorhandler(_vm, _compilererror, _sourcename.isString() == true?_stringval(_sourcename):"unknown",
|
||||||
_lex._currentline, _lex._currentcolumn);
|
_lex._currentline, _lex._currentcolumn);
|
||||||
}
|
}
|
||||||
_vm->_lasterror = rabbit::String::create(_get_shared_state(_vm), _compilererror, -1);
|
_vm->_lasterror = rabbit::String::create(_get_shared_state(_vm), _compilererror, -1);
|
||||||
@ -784,7 +784,7 @@ public:
|
|||||||
/* Handle named constant */
|
/* Handle named constant */
|
||||||
rabbit::ObjectPtr constval;
|
rabbit::ObjectPtr constval;
|
||||||
rabbit::Object constid;
|
rabbit::Object constid;
|
||||||
if(sq_type(constant) == rabbit::OT_TABLE) {
|
if(constant.isTable() == true) {
|
||||||
Expect('.');
|
Expect('.');
|
||||||
constid = Expect(TK_IDENTIFIER);
|
constid = Expect(TK_IDENTIFIER);
|
||||||
if(!constant.toTable()->get(constid, constval)) {
|
if(!constant.toTable()->get(constid, constval)) {
|
||||||
@ -798,12 +798,19 @@ public:
|
|||||||
_es.epos = _fs->pushTarget();
|
_es.epos = _fs->pushTarget();
|
||||||
|
|
||||||
/* generate direct or literal function depending on size */
|
/* generate direct or literal function depending on size */
|
||||||
rabbit::ObjectType ctype = sq_type(constval);
|
switch(constval.getType()) {
|
||||||
switch(ctype) {
|
case rabbit::OT_INTEGER:
|
||||||
case rabbit::OT_INTEGER: EmitloadConstInt(constval.toInteger(),_es.epos); break;
|
EmitloadConstInt(constval.toInteger(),_es.epos);
|
||||||
case rabbit::OT_FLOAT: EmitloadConstFloat(constval.toFloat(),_es.epos); break;
|
break;
|
||||||
case rabbit::OT_BOOL: _fs->addInstruction(_OP_LOADBOOL, _es.epos, constval.toInteger()); break;
|
case rabbit::OT_FLOAT:
|
||||||
default: _fs->addInstruction(_OP_LOAD,_es.epos,_fs->getConstant(constval)); break;
|
EmitloadConstFloat(constval.toFloat(),_es.epos);
|
||||||
|
break;
|
||||||
|
case rabbit::OT_BOOL:
|
||||||
|
_fs->addInstruction(_OP_LOADBOOL, _es.epos, constval.toInteger());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_fs->addInstruction(_OP_LOAD,_es.epos,_fs->getConstant(constval));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
_es.etype = EXPR;
|
_es.etype = EXPR;
|
||||||
}
|
}
|
||||||
|
@ -99,12 +99,22 @@ void rabbit::FuncState::addInstruction(SQOpcode _op,int64_t arg0,int64_t arg1,in
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void dumpLiteral(rabbit::ObjectPtr &o) {
|
static void dumpLiteral(rabbit::ObjectPtr &o) {
|
||||||
switch(sq_type(o)){
|
switch(o.getType()){
|
||||||
case rabbit::OT_STRING: printf("\"%s\"",_stringval(o));break;
|
case rabbit::OT_STRING:
|
||||||
case rabbit::OT_FLOAT: printf("{%f}",o.toFloat());break;
|
printf("\"%s\"",_stringval(o));
|
||||||
case rabbit::OT_INTEGER: printf("{" _PRINT_INT_FMT "}",o.toInteger());break;
|
break;
|
||||||
case rabbit::OT_BOOL: printf("%s",o.toInteger()?"true":"false");break;
|
case rabbit::OT_FLOAT:
|
||||||
default: printf("(%s %p)",getTypeName(o),(void*)o.toRaw());break; break; //shut up compiler
|
printf("{%f}",o.toFloat());
|
||||||
|
break;
|
||||||
|
case rabbit::OT_INTEGER:
|
||||||
|
printf("{" _PRINT_INT_FMT "}",o.toInteger());
|
||||||
|
break;
|
||||||
|
case rabbit::OT_BOOL:
|
||||||
|
printf("%s",o.toInteger()?"true":"false");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("(%s %p)",getTypeName(o),(void*)o.toRaw());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +152,7 @@ void rabbit::FuncState::dump(rabbit::FunctionProto *func)
|
|||||||
printf("rabbit::Instruction sizeof %d\n",(int32_t)sizeof(rabbit::Instruction));
|
printf("rabbit::Instruction sizeof %d\n",(int32_t)sizeof(rabbit::Instruction));
|
||||||
printf("rabbit::Object sizeof %d\n", (int32_t)sizeof(rabbit::Object));
|
printf("rabbit::Object sizeof %d\n", (int32_t)sizeof(rabbit::Object));
|
||||||
printf("--------------------------------------------------------------------\n");
|
printf("--------------------------------------------------------------------\n");
|
||||||
printf("*****FUNCTION [%s]\n",sq_type(func->_name)==rabbit::OT_STRING?_stringval(func->_name):"unknown");
|
printf("*****FUNCTION [%s]\n",func->_name.isString() == true?_stringval(func->_name):"unknown");
|
||||||
printf("-----LITERALS\n");
|
printf("-----LITERALS\n");
|
||||||
rabbit::ObjectPtr refidx,key,val;
|
rabbit::ObjectPtr refidx,key,val;
|
||||||
int64_t idx;
|
int64_t idx;
|
||||||
@ -312,7 +322,7 @@ int64_t rabbit::FuncState::popTarget()
|
|||||||
uint64_t npos=_targetstack.back();
|
uint64_t npos=_targetstack.back();
|
||||||
assert(npos < _vlocals.size());
|
assert(npos < _vlocals.size());
|
||||||
rabbit::LocalVarInfo &t = _vlocals[npos];
|
rabbit::LocalVarInfo &t = _vlocals[npos];
|
||||||
if(sq_type(t._name)==rabbit::OT_NULL){
|
if(t._name.isNull()==true){
|
||||||
_vlocals.popBack();
|
_vlocals.popBack();
|
||||||
}
|
}
|
||||||
_targetstack.popBack();
|
_targetstack.popBack();
|
||||||
@ -344,7 +354,7 @@ void rabbit::FuncState::setStacksize(int64_t n)
|
|||||||
while(size>n){
|
while(size>n){
|
||||||
size--;
|
size--;
|
||||||
rabbit::LocalVarInfo lvi = _vlocals.back();
|
rabbit::LocalVarInfo lvi = _vlocals.back();
|
||||||
if(sq_type(lvi._name)!=rabbit::OT_NULL){
|
if(lvi._name.isNull()==false){
|
||||||
if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer
|
if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer
|
||||||
_outers--;
|
_outers--;
|
||||||
}
|
}
|
||||||
@ -367,8 +377,11 @@ bool rabbit::FuncState::isConstant(const rabbit::Object &name,rabbit::Object &e)
|
|||||||
|
|
||||||
bool rabbit::FuncState::isLocal(uint64_t stkpos)
|
bool rabbit::FuncState::isLocal(uint64_t stkpos)
|
||||||
{
|
{
|
||||||
if(stkpos>=_vlocals.size())return false;
|
if(stkpos>=_vlocals.size()) {
|
||||||
else if(sq_type(_vlocals[stkpos]._name)!=rabbit::OT_NULL)return true;
|
return false;
|
||||||
|
} else if(_vlocals[stkpos]._name.isNull()==false) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,7 +404,8 @@ int64_t rabbit::FuncState::getLocalVariable(const rabbit::Object &name)
|
|||||||
int64_t locals=_vlocals.size();
|
int64_t locals=_vlocals.size();
|
||||||
while(locals>=1){
|
while(locals>=1){
|
||||||
rabbit::LocalVarInfo &lvi = _vlocals[locals-1];
|
rabbit::LocalVarInfo &lvi = _vlocals[locals-1];
|
||||||
if(sq_type(lvi._name)==rabbit::OT_STRING && lvi._name.toString()==name.toString()){
|
if( lvi._name.isString() == true
|
||||||
|
&& lvi._name.toString() == name.toString()){
|
||||||
return locals-1;
|
return locals-1;
|
||||||
}
|
}
|
||||||
locals--;
|
locals--;
|
||||||
|
@ -16,13 +16,23 @@
|
|||||||
|
|
||||||
bool rabbit::Generator::yield(rabbit::VirtualMachine *v,int64_t target)
|
bool rabbit::Generator::yield(rabbit::VirtualMachine *v,int64_t target)
|
||||||
{
|
{
|
||||||
if(_state==eSuspended) { v->raise_error("internal vm error, yielding dead generator"); return false;}
|
if (_state==eSuspended) {
|
||||||
if(_state==eDead) { v->raise_error("internal vm error, yielding a dead generator"); return false; }
|
v->raise_error("internal vm error, yielding dead generator");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (_state==eDead) {
|
||||||
|
v->raise_error("internal vm error, yielding a dead generator");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
int64_t size = v->_top-v->_stackbase;
|
int64_t size = v->_top-v->_stackbase;
|
||||||
|
|
||||||
_stack.resize(size);
|
_stack.resize(size);
|
||||||
rabbit::Object _this = v->_stack[v->_stackbase];
|
rabbit::Object _this = v->_stack[v->_stackbase];
|
||||||
_stack[0] = ISREFCOUNTED(sq_type(_this)) ? rabbit::ObjectPtr(_this.toRefCounted()->getWeakRef(sq_type(_this))) : _this;
|
if (_this.isRefCounted() == true) {
|
||||||
|
_stack[0] = rabbit::ObjectPtr(_this.toRefCounted()->getWeakRef(_this.getType()));
|
||||||
|
} else {
|
||||||
|
_stack[0] = _this;
|
||||||
|
}
|
||||||
for(int64_t n =1; n<target; n++) {
|
for(int64_t n =1; n<target; n++) {
|
||||||
_stack[n] = v->_stack[v->_stackbase+n];
|
_stack[n] = v->_stack[v->_stackbase+n];
|
||||||
}
|
}
|
||||||
@ -74,17 +84,19 @@ bool rabbit::Generator::resume(rabbit::VirtualMachine *v,rabbit::ObjectPtr &dest
|
|||||||
et._stacksize += newbase;
|
et._stacksize += newbase;
|
||||||
}
|
}
|
||||||
rabbit::Object _this = _stack[0];
|
rabbit::Object _this = _stack[0];
|
||||||
v->_stack[v->_stackbase] = sq_type(_this) == rabbit::OT_WEAKREF ? _this.toWeakRef()->_obj : _this;
|
if (_this.isWeakRef() == true) {
|
||||||
|
v->_stack[v->_stackbase] = _this.toWeakRef()->_obj;
|
||||||
|
} else {
|
||||||
|
v->_stack[v->_stackbase] = _this;
|
||||||
|
}
|
||||||
for(int64_t n = 1; n<size; n++) {
|
for(int64_t n = 1; n<size; n++) {
|
||||||
v->_stack[v->_stackbase+n] = _stack[n];
|
v->_stack[v->_stackbase+n] = _stack[n];
|
||||||
_stack[n].Null();
|
_stack[n].Null();
|
||||||
}
|
}
|
||||||
|
|
||||||
_state=eRunning;
|
_state=eRunning;
|
||||||
if (v->_debughook)
|
if (v->_debughook) {
|
||||||
v->callDebugHook('c');
|
v->callDebugHook('c');
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ rabbit::Instance::~Instance() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool rabbit::Instance::getMetaMethod(rabbit::VirtualMachine* SQ_UNUSED_ARG(v),rabbit::MetaMethod mm,rabbit::ObjectPtr &res) {
|
bool rabbit::Instance::getMetaMethod(rabbit::VirtualMachine* SQ_UNUSED_ARG(v),rabbit::MetaMethod mm,rabbit::ObjectPtr &res) {
|
||||||
if(sq_type(_class->_metamethods[mm]) != rabbit::OT_NULL) {
|
if(_class->_metamethods[mm].isNull() == false) {
|
||||||
res = _class->_metamethods[mm];
|
res = _class->_metamethods[mm];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -132,9 +132,15 @@ namespace rabbit {
|
|||||||
uint64_t toRaw() const {
|
uint64_t toRaw() const {
|
||||||
return _unVal.raw;
|
return _unVal.raw;
|
||||||
}
|
}
|
||||||
|
bool isRefCounted() const {
|
||||||
|
return (_type & SQOBJECT_REF_COUNTED) != 0;
|
||||||
|
}
|
||||||
bool isNumeric() const {
|
bool isNumeric() const {
|
||||||
return (_type & SQOBJECT_NUMERIC) != 0;
|
return (_type & SQOBJECT_NUMERIC) != 0;
|
||||||
}
|
}
|
||||||
|
bool canBeFalse() const {
|
||||||
|
return (_type & SQOBJECT_CANBEFALSE) != 0;
|
||||||
|
}
|
||||||
bool isTable() const {
|
bool isTable() const {
|
||||||
return _type == rabbit::OT_TABLE;
|
return _type == rabbit::OT_TABLE;
|
||||||
}
|
}
|
||||||
@ -191,6 +197,8 @@ namespace rabbit {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED)
|
||||||
|
|
||||||
#define __addRef(type,unval) if(ISREFCOUNTED(type)) \
|
#define __addRef(type,unval) if(ISREFCOUNTED(type)) \
|
||||||
{ \
|
{ \
|
||||||
unval.pRefCounted->refCountIncrement(); \
|
unval.pRefCounted->refCountIncrement(); \
|
||||||
@ -201,18 +209,16 @@ namespace rabbit {
|
|||||||
unval.pRefCounted->release(); \
|
unval.pRefCounted->release(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _realval(o) (sq_type((o)) != rabbit::OT_WEAKREF?(rabbit::Object)o:(o).toWeakRef()->_obj)
|
#define _realval(o) ((o).isWeakRef() == false?(rabbit::Object)o:(o).toWeakRef()->_obj)
|
||||||
|
|
||||||
#define is_delegable(t) (sq_type(t)&SQOBJECT_DELEGABLE)
|
#define is_delegable(t) ((t).getType()&SQOBJECT_DELEGABLE)
|
||||||
#define raw_type(obj) _RAW_TYPE((obj)._type)
|
#define raw_type(obj) _RAW_TYPE((obj)._type)
|
||||||
|
|
||||||
#define _stringval(obj) (obj)._unVal.pString->_val
|
#define _stringval(obj) (obj)._unVal.pString->_val
|
||||||
#define _userdataval(obj) ((rabbit::UserPointer)sq_aligning((obj)._unVal.pUserData + 1))
|
#define _userdataval(obj) ((rabbit::UserPointer)sq_aligning((obj)._unVal.pUserData + 1))
|
||||||
|
|
||||||
#define tofloat(num) ((sq_type(num)==rabbit::OT_INTEGER)?(float_t)(num).toInteger():(num).toFloat())
|
#define tofloat(num) (((num).isInteger()==true)?(float_t)(num).toInteger():(num).toFloat())
|
||||||
#define tointeger(num) ((sq_type(num)==rabbit::OT_FLOAT)?(int64_t)(num).toFloat():(num).toInteger())
|
#define tointeger(num) (((num).isFloat()==true)?(int64_t)(num).toFloat():(num).toInteger())
|
||||||
|
|
||||||
#define sq_type(o) ((o)._type)
|
|
||||||
|
|
||||||
inline void _Swap(rabbit::Object &a,rabbit::Object &b)
|
inline void _Swap(rabbit::Object &a,rabbit::Object &b)
|
||||||
{
|
{
|
||||||
|
@ -139,14 +139,15 @@ void rabbit::ObjectPtr::Null() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint64_t rabbit::translateIndex(const rabbit::ObjectPtr &idx)
|
uint64_t rabbit::translateIndex(const rabbit::ObjectPtr &idx) {
|
||||||
{
|
switch(idx.getType()){
|
||||||
switch(sq_type(idx)){
|
|
||||||
case rabbit::OT_NULL:
|
case rabbit::OT_NULL:
|
||||||
return 0;
|
return 0;
|
||||||
case rabbit::OT_INTEGER:
|
case rabbit::OT_INTEGER:
|
||||||
return (uint64_t)idx.toInteger();
|
return (uint64_t)idx.toInteger();
|
||||||
default: assert(0); break;
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -154,8 +155,7 @@ uint64_t rabbit::translateIndex(const rabbit::ObjectPtr &idx)
|
|||||||
|
|
||||||
const char* rabbit::IdType2Name(rabbit::ObjectType type)
|
const char* rabbit::IdType2Name(rabbit::ObjectType type)
|
||||||
{
|
{
|
||||||
switch(_RAW_TYPE(type))
|
switch(_RAW_TYPE(type)) {
|
||||||
{
|
|
||||||
case _RT_NULL:
|
case _RT_NULL:
|
||||||
return "null";
|
return "null";
|
||||||
case _RT_INTEGER:
|
case _RT_INTEGER:
|
||||||
@ -197,5 +197,5 @@ const char* rabbit::IdType2Name(rabbit::ObjectType type)
|
|||||||
|
|
||||||
const char* rabbit::getTypeName(const rabbit::ObjectPtr &obj1)
|
const char* rabbit::getTypeName(const rabbit::ObjectPtr &obj1)
|
||||||
{
|
{
|
||||||
return IdType2Name(sq_type(obj1));
|
return IdType2Name(obj1.getType());
|
||||||
}
|
}
|
||||||
|
@ -61,5 +61,4 @@ namespace rabbit {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED)
|
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ void rabbit::RefTable::resize(uint64_t size)
|
|||||||
//rehash
|
//rehash
|
||||||
uint64_t nfound = 0;
|
uint64_t nfound = 0;
|
||||||
for(uint64_t n = 0; n < oldnumofslots; n++) {
|
for(uint64_t n = 0; n < oldnumofslots; n++) {
|
||||||
if(sq_type(t->obj) != rabbit::OT_NULL) {
|
if(t->obj.isNull() == false) {
|
||||||
//add back;
|
//add back;
|
||||||
assert(t->refs != 0);
|
assert(t->refs != 0);
|
||||||
RefNode *nn = add(rabbit::HashObj(t->obj)&(_numofslots-1),t->obj);
|
RefNode *nn = add(rabbit::HashObj(t->obj)&(_numofslots-1),t->obj);
|
||||||
@ -118,7 +118,8 @@ rabbit::RefTable::RefNode* rabbit::RefTable::get(rabbit::Object &obj,rabbit::Has
|
|||||||
mainpos = rabbit::HashObj(obj)&(_numofslots-1);
|
mainpos = rabbit::HashObj(obj)&(_numofslots-1);
|
||||||
*prev = NULL;
|
*prev = NULL;
|
||||||
for (ref = _buckets[mainpos]; ref; ) {
|
for (ref = _buckets[mainpos]; ref; ) {
|
||||||
if(ref->obj.toRaw() == obj.toRaw() && sq_type(ref->obj) == sq_type(obj))
|
if( ref->obj.toRaw() == obj.toRaw()
|
||||||
|
&& ref->obj.getType() == obj.getType())
|
||||||
break;
|
break;
|
||||||
*prev = ref;
|
*prev = ref;
|
||||||
ref = ref->next;
|
ref = ref->next;
|
||||||
|
@ -195,7 +195,7 @@ rabbit::SharedState::~SharedState()
|
|||||||
|
|
||||||
|
|
||||||
int64_t rabbit::SharedState::getMetaMethodIdxByName(const rabbit::ObjectPtr &name) {
|
int64_t rabbit::SharedState::getMetaMethodIdxByName(const rabbit::ObjectPtr &name) {
|
||||||
if(sq_type(name) != rabbit::OT_STRING) {
|
if(name.isString() == false) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
rabbit::ObjectPtr ret;
|
rabbit::ObjectPtr ret;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#include <etk/Allocator.hpp>
|
#include <etk/Allocator.hpp>
|
||||||
|
|
||||||
rabbit::Hash rabbit::HashObj(const rabbit::ObjectPtr &key) {
|
rabbit::Hash rabbit::HashObj(const rabbit::ObjectPtr &key) {
|
||||||
switch(sq_type(key)) {
|
switch(key.getType()) {
|
||||||
case rabbit::OT_STRING:
|
case rabbit::OT_STRING:
|
||||||
return key.toString()->_hash;
|
return key.toString()->_hash;
|
||||||
case rabbit::OT_FLOAT:
|
case rabbit::OT_FLOAT:
|
||||||
@ -62,23 +62,28 @@ void rabbit::Table::Rehash(bool force) const
|
|||||||
{
|
{
|
||||||
int64_t oldsize=_numofnodes;
|
int64_t oldsize=_numofnodes;
|
||||||
//prevent problems with the integer division
|
//prevent problems with the integer division
|
||||||
if(oldsize<4)oldsize=4;
|
if(oldsize<4) {
|
||||||
|
oldsize=4;
|
||||||
|
}
|
||||||
_HashNode *nold=_nodes;
|
_HashNode *nold=_nodes;
|
||||||
int64_t nelems=countUsed();
|
int64_t nelems=countUsed();
|
||||||
if (nelems >= oldsize-oldsize/4) /* using more than 3/4? */
|
if (nelems >= oldsize-oldsize/4) {
|
||||||
|
/* using more than 3/4? */
|
||||||
allocNodes(oldsize*2);
|
allocNodes(oldsize*2);
|
||||||
else if (nelems <= oldsize/4 && /* less than 1/4? */
|
} else if ( nelems <= oldsize/4 /* less than 1/4? */
|
||||||
oldsize > MINPOWER2)
|
&& oldsize > MINPOWER2) {
|
||||||
allocNodes(oldsize/2);
|
allocNodes(oldsize/2);
|
||||||
else if(force)
|
} else if(force) {
|
||||||
allocNodes(oldsize);
|
allocNodes(oldsize);
|
||||||
else
|
} else {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
_usednodes = 0;
|
_usednodes = 0;
|
||||||
for (int64_t i=0; i<oldsize; i++) {
|
for (int64_t i=0; i<oldsize; i++) {
|
||||||
_HashNode *old = nold+i;
|
_HashNode *old = nold+i;
|
||||||
if (sq_type(old->key) != rabbit::OT_NULL)
|
if (old->key.isNull() == false) {
|
||||||
newSlot(old->key,old->val);
|
newSlot(old->key,old->val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for(int64_t k=0;k<oldsize;k++)
|
for(int64_t k=0;k<oldsize;k++)
|
||||||
nold[k].~_HashNode();
|
nold[k].~_HashNode();
|
||||||
@ -122,7 +127,7 @@ rabbit::Table *rabbit::Table::clone() const
|
|||||||
|
|
||||||
bool rabbit::Table::get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val) const
|
bool rabbit::Table::get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val) const
|
||||||
{
|
{
|
||||||
if(sq_type(key) == rabbit::OT_NULL)
|
if(key.isNull() == true)
|
||||||
return false;
|
return false;
|
||||||
_HashNode *n = _get(key, HashObj(key) & (_numofnodes - 1));
|
_HashNode *n = _get(key, HashObj(key) & (_numofnodes - 1));
|
||||||
if (n) {
|
if (n) {
|
||||||
@ -133,7 +138,7 @@ bool rabbit::Table::get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val) con
|
|||||||
}
|
}
|
||||||
bool rabbit::Table::newSlot(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val) const
|
bool rabbit::Table::newSlot(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val) const
|
||||||
{
|
{
|
||||||
assert(sq_type(key) != rabbit::OT_NULL);
|
assert(key.isNull() == false);
|
||||||
rabbit::Hash h = HashObj(key) & (_numofnodes - 1);
|
rabbit::Hash h = HashObj(key) & (_numofnodes - 1);
|
||||||
_HashNode *n = _get(key, h);
|
_HashNode *n = _get(key, h);
|
||||||
if (n) {
|
if (n) {
|
||||||
@ -147,7 +152,7 @@ bool rabbit::Table::newSlot(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr
|
|||||||
//key not found I'll insert it
|
//key not found I'll insert it
|
||||||
//main pos is not free
|
//main pos is not free
|
||||||
|
|
||||||
if(sq_type(mp->key) != rabbit::OT_NULL) {
|
if(mp->key.isNull() == false) {
|
||||||
n = _firstfree; /* get a free place */
|
n = _firstfree; /* get a free place */
|
||||||
rabbit::Hash mph = HashObj(mp->key) & (_numofnodes - 1);
|
rabbit::Hash mph = HashObj(mp->key) & (_numofnodes - 1);
|
||||||
_HashNode *othern; /* main position of colliding node */
|
_HashNode *othern; /* main position of colliding node */
|
||||||
@ -165,8 +170,7 @@ bool rabbit::Table::newSlot(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr
|
|||||||
mp->key.Null();
|
mp->key.Null();
|
||||||
mp->val.Null();
|
mp->val.Null();
|
||||||
mp->next = NULL; /* now `mp' is free */
|
mp->next = NULL; /* now `mp' is free */
|
||||||
}
|
} else{
|
||||||
else{
|
|
||||||
/* new node will go into free position */
|
/* new node will go into free position */
|
||||||
n->next = mp->next; /* chain new position */
|
n->next = mp->next; /* chain new position */
|
||||||
mp->next = n;
|
mp->next = n;
|
||||||
@ -175,14 +179,18 @@ bool rabbit::Table::newSlot(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr
|
|||||||
}
|
}
|
||||||
mp->key = key;
|
mp->key = key;
|
||||||
|
|
||||||
for (;;) { /* correct `firstfree' */
|
for (;;) {
|
||||||
if (sq_type(_firstfree->key) == rabbit::OT_NULL && _firstfree->next == NULL) {
|
/* correct `firstfree' */
|
||||||
|
if ( _firstfree->key.isNull() == true
|
||||||
|
&& _firstfree->next == NULL) {
|
||||||
mp->val = val;
|
mp->val = val;
|
||||||
_usednodes++;
|
_usednodes++;
|
||||||
return true; /* OK; table still has a free place */
|
return true; /* OK; table still has a free place */
|
||||||
|
} else if (_firstfree == _nodes) {
|
||||||
|
break; /* cannot decrement from here */
|
||||||
|
} else {
|
||||||
|
(_firstfree)--;
|
||||||
}
|
}
|
||||||
else if (_firstfree == _nodes) break; /* cannot decrement from here */
|
|
||||||
else (_firstfree)--;
|
|
||||||
}
|
}
|
||||||
Rehash(true);
|
Rehash(true);
|
||||||
return newSlot(key, val);
|
return newSlot(key, val);
|
||||||
@ -192,7 +200,7 @@ int64_t rabbit::Table::next(bool getweakrefs,const rabbit::ObjectPtr &refpos, ra
|
|||||||
{
|
{
|
||||||
int64_t idx = (int64_t)translateIndex(refpos);
|
int64_t idx = (int64_t)translateIndex(refpos);
|
||||||
while (idx < _numofnodes) {
|
while (idx < _numofnodes) {
|
||||||
if(sq_type(_nodes[idx].key) != rabbit::OT_NULL) {
|
if(_nodes[idx].key.isNull() == false) {
|
||||||
//first found
|
//first found
|
||||||
_HashNode &n = _nodes[idx];
|
_HashNode &n = _nodes[idx];
|
||||||
outkey = n.key;
|
outkey = n.key;
|
||||||
@ -254,7 +262,7 @@ rabbit::Table::_HashNode* rabbit::Table::_get(const rabbit::ObjectPtr &key,rabbi
|
|||||||
_HashNode *n = &_nodes[hash];
|
_HashNode *n = &_nodes[hash];
|
||||||
do {
|
do {
|
||||||
if( n->key.toRaw() == key.toRaw()
|
if( n->key.toRaw() == key.toRaw()
|
||||||
&& sq_type(n->key) == sq_type(key)){
|
&& n->key.getType() == key.getType()){
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
} while((n = n->next));
|
} while((n = n->next));
|
||||||
@ -266,12 +274,13 @@ bool rabbit::Table::getStr(const char* key,int64_t keylen,rabbit::ObjectPtr &val
|
|||||||
rabbit::Hash hash = _hashstr(key,keylen);
|
rabbit::Hash hash = _hashstr(key,keylen);
|
||||||
_HashNode *n = &_nodes[hash & (_numofnodes - 1)];
|
_HashNode *n = &_nodes[hash & (_numofnodes - 1)];
|
||||||
_HashNode *res = NULL;
|
_HashNode *res = NULL;
|
||||||
do{
|
do {
|
||||||
if(sq_type(n->key) == rabbit::OT_STRING && (strcmp(_stringval(n->key),key) == 0)){
|
if ( n->key.isString() == true
|
||||||
|
&& strcmp(_stringval(n->key), key) == 0) {
|
||||||
res = n;
|
res = n;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}while((n = n->next));
|
} while((n = n->next));
|
||||||
if (res) {
|
if (res) {
|
||||||
val = _realval(res->val);
|
val = _realval(res->val);
|
||||||
return true;
|
return true;
|
||||||
|
@ -37,16 +37,28 @@
|
|||||||
bool rabbit::VirtualMachine::BW_OP(uint64_t op,rabbit::ObjectPtr &trg,const rabbit::ObjectPtr &o1,const rabbit::ObjectPtr &o2)
|
bool rabbit::VirtualMachine::BW_OP(uint64_t op,rabbit::ObjectPtr &trg,const rabbit::ObjectPtr &o1,const rabbit::ObjectPtr &o2)
|
||||||
{
|
{
|
||||||
int64_t res;
|
int64_t res;
|
||||||
if((sq_type(o1)| sq_type(o2)) == rabbit::OT_INTEGER)
|
if((o1.getType()| o2.getType()) == rabbit::OT_INTEGER)
|
||||||
{
|
{
|
||||||
int64_t i1 = o1.toInteger(), i2 = o2.toInteger();
|
int64_t i1 = o1.toInteger(), i2 = o2.toInteger();
|
||||||
switch(op) {
|
switch(op) {
|
||||||
case BW_AND: res = i1 & i2; break;
|
case BW_AND:
|
||||||
case BW_OR: res = i1 | i2; break;
|
res = i1 & i2;
|
||||||
case BW_XOR: res = i1 ^ i2; break;
|
break;
|
||||||
case BW_SHIFTL: res = i1 << i2; break;
|
case BW_OR:
|
||||||
case BW_SHIFTR: res = i1 >> i2; break;
|
res = i1 | i2;
|
||||||
case BW_USHIFTR:res = (int64_t)(*((uint64_t*)&i1) >> i2); break;
|
break;
|
||||||
|
case BW_XOR:
|
||||||
|
res = i1 ^ i2;
|
||||||
|
break;
|
||||||
|
case BW_SHIFTL:
|
||||||
|
res = i1 << i2;
|
||||||
|
break;
|
||||||
|
case BW_SHIFTR:
|
||||||
|
res = i1 >> i2;
|
||||||
|
break;
|
||||||
|
case BW_USHIFTR:
|
||||||
|
res = (int64_t)(*((uint64_t*)&i1) >> i2);
|
||||||
|
break;
|
||||||
default: { raise_error("internal vm error bitwise op failed"); return false; }
|
default: { raise_error("internal vm error bitwise op failed"); return false; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -61,7 +73,7 @@ void rabbit::VirtualMachine::release() {
|
|||||||
|
|
||||||
#define _ARITH_(op,trg,o1,o2) \
|
#define _ARITH_(op,trg,o1,o2) \
|
||||||
{ \
|
{ \
|
||||||
int64_t tmask = sq_type(o1)|sq_type(o2); \
|
int64_t tmask = o1.getType()|o2.getType(); \
|
||||||
switch(tmask) { \
|
switch(tmask) { \
|
||||||
case rabbit::OT_INTEGER: trg = o1.toInteger() op o2.toInteger();break; \
|
case rabbit::OT_INTEGER: trg = o1.toInteger() op o2.toInteger();break; \
|
||||||
case (rabbit::OT_FLOAT|OT_INTEGER): \
|
case (rabbit::OT_FLOAT|OT_INTEGER): \
|
||||||
@ -72,7 +84,7 @@ void rabbit::VirtualMachine::release() {
|
|||||||
|
|
||||||
#define _ARITH_NOZERO(op,trg,o1,o2,err) \
|
#define _ARITH_NOZERO(op,trg,o1,o2,err) \
|
||||||
{ \
|
{ \
|
||||||
int64_t tmask = sq_type(o1)|sq_type(o2); \
|
int64_t tmask = o1.getType()|o2.getType(); \
|
||||||
switch(tmask) { \
|
switch(tmask) { \
|
||||||
case rabbit::OT_INTEGER: { int64_t i2 = o2.toInteger(); if(i2 == 0) { raise_error(err); SQ_THROW(); } trg = o1.toInteger() op i2; } break;\
|
case rabbit::OT_INTEGER: { int64_t i2 = o2.toInteger(); if(i2 == 0) { raise_error(err); SQ_THROW(); } trg = o1.toInteger() op i2; } break;\
|
||||||
case (rabbit::OT_FLOAT|OT_INTEGER): \
|
case (rabbit::OT_FLOAT|OT_INTEGER): \
|
||||||
@ -83,7 +95,7 @@ void rabbit::VirtualMachine::release() {
|
|||||||
|
|
||||||
bool rabbit::VirtualMachine::ARITH_OP(uint64_t op,rabbit::ObjectPtr &trg,const rabbit::ObjectPtr &o1,const rabbit::ObjectPtr &o2)
|
bool rabbit::VirtualMachine::ARITH_OP(uint64_t op,rabbit::ObjectPtr &trg,const rabbit::ObjectPtr &o1,const rabbit::ObjectPtr &o2)
|
||||||
{
|
{
|
||||||
int64_t tmask = sq_type(o1)| sq_type(o2);
|
int64_t tmask = o1.getType() | o2.getType();
|
||||||
switch(tmask) {
|
switch(tmask) {
|
||||||
case rabbit::OT_INTEGER:{
|
case rabbit::OT_INTEGER:{
|
||||||
int64_t res, i1 = o1.toInteger(), i2 = o2.toInteger();
|
int64_t res, i1 = o1.toInteger(), i2 = o2.toInteger();
|
||||||
@ -196,27 +208,29 @@ bool rabbit::VirtualMachine::arithMetaMethod(int64_t op,const rabbit::ObjectPtr
|
|||||||
bool rabbit::VirtualMachine::NEG_OP(rabbit::ObjectPtr &trg,const rabbit::ObjectPtr &o)
|
bool rabbit::VirtualMachine::NEG_OP(rabbit::ObjectPtr &trg,const rabbit::ObjectPtr &o)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch(sq_type(o)) {
|
switch(o.getType()) {
|
||||||
case rabbit::OT_INTEGER:
|
case rabbit::OT_INTEGER:
|
||||||
trg = -o.toInteger();
|
trg = -o.toInteger();
|
||||||
return true;
|
return true;
|
||||||
case rabbit::OT_FLOAT:
|
case rabbit::OT_FLOAT:
|
||||||
trg = -o.toFloat();
|
trg = -o.toFloat();
|
||||||
return true;
|
return true;
|
||||||
case rabbit::OT_TABLE:
|
case rabbit::OT_TABLE:
|
||||||
case rabbit::OT_USERDATA:
|
case rabbit::OT_USERDATA:
|
||||||
case rabbit::OT_INSTANCE:
|
case rabbit::OT_INSTANCE:
|
||||||
if(o.toDelegable()->_delegate) {
|
if(o.toDelegable()->_delegate) {
|
||||||
rabbit::ObjectPtr closure;
|
rabbit::ObjectPtr closure;
|
||||||
if(o.toDelegable()->getMetaMethod(this, MT_UNM, closure)) {
|
if(o.toDelegable()->getMetaMethod(this, MT_UNM, closure)) {
|
||||||
push(o);
|
push(o);
|
||||||
if(!callMetaMethod(closure, MT_UNM, 1, temp_reg)) return false;
|
if(callMetaMethod(closure, MT_UNM, 1, temp_reg) == false) {
|
||||||
_Swap(trg,temp_reg);
|
return false;
|
||||||
return true;
|
}
|
||||||
|
_Swap(trg,temp_reg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
default:
|
||||||
default:break; //shutup compiler
|
break; //shutup compiler
|
||||||
}
|
}
|
||||||
raise_error("attempt to negate a %s", getTypeName(o));
|
raise_error("attempt to negate a %s", getTypeName(o));
|
||||||
return false;
|
return false;
|
||||||
@ -225,7 +239,8 @@ bool rabbit::VirtualMachine::NEG_OP(rabbit::ObjectPtr &trg,const rabbit::ObjectP
|
|||||||
#define _RET_SUCCEED(exp) { result = (exp); return true; }
|
#define _RET_SUCCEED(exp) { result = (exp); return true; }
|
||||||
bool rabbit::VirtualMachine::objCmp(const rabbit::ObjectPtr &o1,const rabbit::ObjectPtr &o2,int64_t &result)
|
bool rabbit::VirtualMachine::objCmp(const rabbit::ObjectPtr &o1,const rabbit::ObjectPtr &o2,int64_t &result)
|
||||||
{
|
{
|
||||||
rabbit::ObjectType t1 = sq_type(o1), t2 = sq_type(o2);
|
rabbit::ObjectType t1 = o1.getType();
|
||||||
|
rabbit::ObjectType t2 = o2.getType();
|
||||||
if(t1 == t2) {
|
if(t1 == t2) {
|
||||||
if(o1.toRaw() == o2.toRaw())_RET_SUCCEED(0);
|
if(o1.toRaw() == o2.toRaw())_RET_SUCCEED(0);
|
||||||
rabbit::ObjectPtr res;
|
rabbit::ObjectPtr res;
|
||||||
@ -244,7 +259,7 @@ bool rabbit::VirtualMachine::objCmp(const rabbit::ObjectPtr &o1,const rabbit::Ob
|
|||||||
if(o1.toDelegable()->getMetaMethod(this, MT_CMP, closure)) {
|
if(o1.toDelegable()->getMetaMethod(this, MT_CMP, closure)) {
|
||||||
push(o1);push(o2);
|
push(o1);push(o2);
|
||||||
if(callMetaMethod(closure,MT_CMP,2,res)) {
|
if(callMetaMethod(closure,MT_CMP,2,res)) {
|
||||||
if(sq_type(res) != rabbit::OT_INTEGER) {
|
if(res.isInteger() == false) {
|
||||||
raise_error("_cmp must return an integer");
|
raise_error("_cmp must return an integer");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -303,37 +318,37 @@ bool rabbit::VirtualMachine::CMP_OP(CmpOP op, const rabbit::ObjectPtr &o1,const
|
|||||||
|
|
||||||
bool rabbit::VirtualMachine::toString(const rabbit::ObjectPtr &o,rabbit::ObjectPtr &res)
|
bool rabbit::VirtualMachine::toString(const rabbit::ObjectPtr &o,rabbit::ObjectPtr &res)
|
||||||
{
|
{
|
||||||
switch(sq_type(o)) {
|
switch(o.getType()) {
|
||||||
case rabbit::OT_STRING:
|
case rabbit::OT_STRING:
|
||||||
res = o;
|
res = o;
|
||||||
return true;
|
return true;
|
||||||
case rabbit::OT_FLOAT:
|
case rabbit::OT_FLOAT:
|
||||||
snprintf(_sp(sq_rsl(NUMBER_UINT8_MAX+1)),sq_rsl(NUMBER_UINT8_MAX),"%g",o.toFloat());
|
snprintf(_sp(sq_rsl(NUMBER_UINT8_MAX+1)),sq_rsl(NUMBER_UINT8_MAX),"%g",o.toFloat());
|
||||||
break;
|
break;
|
||||||
case rabbit::OT_INTEGER:
|
case rabbit::OT_INTEGER:
|
||||||
snprintf(_sp(sq_rsl(NUMBER_UINT8_MAX+1)),sq_rsl(NUMBER_UINT8_MAX),_PRINT_INT_FMT,o.toInteger());
|
snprintf(_sp(sq_rsl(NUMBER_UINT8_MAX+1)),sq_rsl(NUMBER_UINT8_MAX),_PRINT_INT_FMT,o.toInteger());
|
||||||
break;
|
break;
|
||||||
case rabbit::OT_BOOL:
|
case rabbit::OT_BOOL:
|
||||||
snprintf(_sp(sq_rsl(6)),sq_rsl(6),o.toInteger()?"true":"false");
|
snprintf(_sp(sq_rsl(6)),sq_rsl(6),o.toInteger()?"true":"false");
|
||||||
break;
|
break;
|
||||||
case rabbit::OT_TABLE:
|
case rabbit::OT_TABLE:
|
||||||
case rabbit::OT_USERDATA:
|
case rabbit::OT_USERDATA:
|
||||||
case rabbit::OT_INSTANCE:
|
case rabbit::OT_INSTANCE:
|
||||||
if(o.toDelegable()->_delegate) {
|
if(o.toDelegable()->_delegate) {
|
||||||
rabbit::ObjectPtr closure;
|
rabbit::ObjectPtr closure;
|
||||||
if(o.toDelegable()->getMetaMethod(this, MT_TOSTRING, closure)) {
|
if(o.toDelegable()->getMetaMethod(this, MT_TOSTRING, closure)) {
|
||||||
push(o);
|
push(o);
|
||||||
if(callMetaMethod(closure,MT_TOSTRING,1,res)) {
|
if(callMetaMethod(closure,MT_TOSTRING,1,res)) {
|
||||||
if(sq_type(res) == rabbit::OT_STRING)
|
if(res.isString() == true) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
default:
|
||||||
default:
|
snprintf(_sp(sq_rsl((sizeof(void*)*2)+NUMBER_UINT8_MAX)),sq_rsl((sizeof(void*)*2)+NUMBER_UINT8_MAX),"(%s : 0x%p)",getTypeName(o),(void*)o.toRaw());
|
||||||
snprintf(_sp(sq_rsl((sizeof(void*)*2)+NUMBER_UINT8_MAX)),sq_rsl((sizeof(void*)*2)+NUMBER_UINT8_MAX),"(%s : 0x%p)",getTypeName(o),(void*)o.toRaw());
|
|
||||||
}
|
}
|
||||||
res = rabbit::String::create(_get_shared_state(this),_spval);
|
res = rabbit::String::create(_get_shared_state(this),_spval);
|
||||||
return true;
|
return true;
|
||||||
@ -534,63 +549,72 @@ rabbit::Result rabbit::VirtualMachine::Suspend()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define _FINISH(howmuchtojump) {jump = howmuchtojump; return true; }
|
#define _FINISH(howmuchtojump) \
|
||||||
|
{ \
|
||||||
|
jump = howmuchtojump; \
|
||||||
|
return true; \
|
||||||
|
}
|
||||||
|
|
||||||
bool rabbit::VirtualMachine::FOREACH_OP(rabbit::ObjectPtr &o1,rabbit::ObjectPtr &o2,rabbit::ObjectPtr
|
bool rabbit::VirtualMachine::FOREACH_OP(rabbit::ObjectPtr &o1,rabbit::ObjectPtr &o2,rabbit::ObjectPtr
|
||||||
&o3,rabbit::ObjectPtr &o4,int64_t SQ_UNUSED_ARG(arg_2),int exitpos,int &jump)
|
&o3,rabbit::ObjectPtr &o4,int64_t SQ_UNUSED_ARG(arg_2),int exitpos,int &jump)
|
||||||
{
|
{
|
||||||
int64_t nrefidx;
|
int64_t nrefidx;
|
||||||
switch(sq_type(o1)) {
|
switch(o1.getType()) {
|
||||||
case rabbit::OT_TABLE:
|
case rabbit::OT_TABLE:
|
||||||
if((nrefidx = o1.toTable()->next(false,o4, o2, o3)) == -1) _FINISH(exitpos);
|
if((nrefidx = o1.toTable()->next(false,o4, o2, o3)) == -1) _FINISH(exitpos);
|
||||||
o4 = (int64_t)nrefidx; _FINISH(1);
|
o4 = (int64_t)nrefidx; _FINISH(1);
|
||||||
case rabbit::OT_ARRAY:
|
case rabbit::OT_ARRAY:
|
||||||
if((nrefidx = o1.toArray()->next(o4, o2, o3)) == -1) _FINISH(exitpos);
|
if((nrefidx = o1.toArray()->next(o4, o2, o3)) == -1) _FINISH(exitpos);
|
||||||
o4 = (int64_t) nrefidx; _FINISH(1);
|
o4 = (int64_t) nrefidx; _FINISH(1);
|
||||||
case rabbit::OT_STRING:
|
case rabbit::OT_STRING:
|
||||||
if((nrefidx = o1.toString()->next(o4, o2, o3)) == -1)_FINISH(exitpos);
|
if((nrefidx = o1.toString()->next(o4, o2, o3)) == -1)_FINISH(exitpos);
|
||||||
o4 = (int64_t)nrefidx; _FINISH(1);
|
o4 = (int64_t)nrefidx; _FINISH(1);
|
||||||
case rabbit::OT_CLASS:
|
case rabbit::OT_CLASS:
|
||||||
if((nrefidx = o1.toClass()->next(o4, o2, o3)) == -1)_FINISH(exitpos);
|
if((nrefidx = o1.toClass()->next(o4, o2, o3)) == -1)_FINISH(exitpos);
|
||||||
o4 = (int64_t)nrefidx; _FINISH(1);
|
o4 = (int64_t)nrefidx; _FINISH(1);
|
||||||
case rabbit::OT_USERDATA:
|
case rabbit::OT_USERDATA:
|
||||||
case rabbit::OT_INSTANCE:
|
case rabbit::OT_INSTANCE:
|
||||||
if(o1.toDelegable()->_delegate) {
|
if(o1.toDelegable()->_delegate) {
|
||||||
rabbit::ObjectPtr itr;
|
rabbit::ObjectPtr itr;
|
||||||
rabbit::ObjectPtr closure;
|
rabbit::ObjectPtr closure;
|
||||||
if(o1.toDelegable()->getMetaMethod(this, MT_NEXTI, closure)) {
|
if(o1.toDelegable()->getMetaMethod(this, MT_NEXTI, closure)) {
|
||||||
push(o1);
|
push(o1);
|
||||||
push(o4);
|
push(o4);
|
||||||
if(callMetaMethod(closure, MT_NEXTI, 2, itr)) {
|
if(callMetaMethod(closure, MT_NEXTI, 2, itr)) {
|
||||||
o4 = o2 = itr;
|
o4 = o2 = itr;
|
||||||
if(sq_type(itr) == rabbit::OT_NULL) _FINISH(exitpos);
|
if(itr.isNull() == true) {
|
||||||
if(!get(o1, itr, o3, 0, DONT_FALL_BACK)) {
|
_FINISH(exitpos);
|
||||||
raise_error("_nexti returned an invalid idx"); // cloud be changed
|
}
|
||||||
|
if(!get(o1, itr, o3, 0, DONT_FALL_BACK)) {
|
||||||
|
raise_error("_nexti returned an invalid idx"); // cloud be changed
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_FINISH(1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_FINISH(1);
|
|
||||||
}
|
}
|
||||||
else {
|
raise_error("_nexti failed");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case rabbit::OT_GENERATOR:
|
||||||
|
if(o1.toGenerator()->_state == rabbit::Generator::eDead) {
|
||||||
|
_FINISH(exitpos);
|
||||||
|
}
|
||||||
|
if(o1.toGenerator()->_state == rabbit::Generator::eSuspended) {
|
||||||
|
int64_t idx = 0;
|
||||||
|
if(o4.isInteger() == true) {
|
||||||
|
idx = o4.toInteger() + 1;
|
||||||
}
|
}
|
||||||
|
o2 = idx;
|
||||||
|
o4 = idx;
|
||||||
|
o1.toGenerator()->resume(this, o3);
|
||||||
|
_FINISH(0);
|
||||||
}
|
}
|
||||||
raise_error("_nexti failed");
|
default:
|
||||||
return false;
|
raise_error("cannot iterate %s", getTypeName(o1));
|
||||||
}
|
|
||||||
break;
|
|
||||||
case rabbit::OT_GENERATOR:
|
|
||||||
if(o1.toGenerator()->_state == rabbit::Generator::eDead) _FINISH(exitpos);
|
|
||||||
if(o1.toGenerator()->_state == rabbit::Generator::eSuspended) {
|
|
||||||
int64_t idx = 0;
|
|
||||||
if(sq_type(o4) == rabbit::OT_INTEGER) {
|
|
||||||
idx = o4.toInteger() + 1;
|
|
||||||
}
|
|
||||||
o2 = idx;
|
|
||||||
o4 = idx;
|
|
||||||
o1.toGenerator()->resume(this, o3);
|
|
||||||
_FINISH(0);
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
raise_error("cannot iterate %s", getTypeName(o1));
|
|
||||||
}
|
}
|
||||||
return false; //cannot be hit(just to avoid warnings)
|
return false; //cannot be hit(just to avoid warnings)
|
||||||
}
|
}
|
||||||
@ -636,14 +660,17 @@ bool rabbit::VirtualMachine::CLASS_OP(rabbit::ObjectPtr &target,int64_t baseclas
|
|||||||
rabbit::Class *base = NULL;
|
rabbit::Class *base = NULL;
|
||||||
rabbit::ObjectPtr attrs;
|
rabbit::ObjectPtr attrs;
|
||||||
if(baseclass != -1) {
|
if(baseclass != -1) {
|
||||||
if(sq_type(_stack[_stackbase+baseclass]) != rabbit::OT_CLASS) { raise_error("trying to inherit from a %s",getTypeName(_stack[_stackbase+baseclass])); return false; }
|
if(_stack[_stackbase+baseclass].isClass() == false) {
|
||||||
|
raise_error("trying to inherit from a %s",getTypeName(_stack[_stackbase+baseclass]));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
base = _stack[_stackbase + baseclass].toClass();
|
base = _stack[_stackbase + baseclass].toClass();
|
||||||
}
|
}
|
||||||
if(attributes != MAX_FUNC_STACKSIZE) {
|
if(attributes != MAX_FUNC_STACKSIZE) {
|
||||||
attrs = _stack[_stackbase+attributes];
|
attrs = _stack[_stackbase+attributes];
|
||||||
}
|
}
|
||||||
target = rabbit::Class::create(_get_shared_state(this),base);
|
target = rabbit::Class::create(_get_shared_state(this),base);
|
||||||
if(sq_type(target.toClass()->_metamethods[MT_INHERITED]) != rabbit::OT_NULL) {
|
if(target.toClass()->_metamethods[MT_INHERITED].isNull() == false) {
|
||||||
int nparams = 2;
|
int nparams = 2;
|
||||||
rabbit::ObjectPtr ret;
|
rabbit::ObjectPtr ret;
|
||||||
push(target); push(attrs);
|
push(target); push(attrs);
|
||||||
@ -659,14 +686,13 @@ bool rabbit::VirtualMachine::CLASS_OP(rabbit::ObjectPtr &target,int64_t baseclas
|
|||||||
|
|
||||||
bool rabbit::VirtualMachine::isEqual(const rabbit::ObjectPtr &o1,const rabbit::ObjectPtr &o2,bool &res)
|
bool rabbit::VirtualMachine::isEqual(const rabbit::ObjectPtr &o1,const rabbit::ObjectPtr &o2,bool &res)
|
||||||
{
|
{
|
||||||
if(sq_type(o1) == sq_type(o2)) {
|
if(o1.getType() == o2.getType()) {
|
||||||
res = (o1.toRaw() == o2.toRaw());
|
res = (o1.toRaw() == o2.toRaw());
|
||||||
}
|
} else {
|
||||||
else {
|
if( o1.isNumeric() == true
|
||||||
if(o1.isNumeric() && o2.isNumeric()) {
|
&& o2.isNumeric() == true) {
|
||||||
res = (tofloat(o1) == tofloat(o2));
|
res = (tofloat(o1) == tofloat(o2));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
res = false;
|
res = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -675,14 +701,20 @@ bool rabbit::VirtualMachine::isEqual(const rabbit::ObjectPtr &o1,const rabbit::O
|
|||||||
|
|
||||||
bool rabbit::VirtualMachine::IsFalse(rabbit::ObjectPtr &o)
|
bool rabbit::VirtualMachine::IsFalse(rabbit::ObjectPtr &o)
|
||||||
{
|
{
|
||||||
if(((sq_type(o) & SQOBJECT_CANBEFALSE)
|
// this is really strange ...
|
||||||
&& ( ((sq_type(o) == rabbit::OT_FLOAT) && (o.toFloat() == float_t(0.0))) ))
|
if ( ( o.canBeFalse() == true
|
||||||
|| (o.toInteger() == 0) ) //rabbit::OT_NULL|OT_INTEGER|OT_BOOL
|
&& ( o.isFloat() == true
|
||||||
|
&& o.toFloat() == 0.0f
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|| o.toInteger() == 0
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern rabbit::InstructionDesc g_InstrDesc[];
|
extern rabbit::InstructionDesc g_InstrDesc[];
|
||||||
bool rabbit::VirtualMachine::execute(rabbit::ObjectPtr &closure, int64_t nargs, int64_t stackbase,rabbit::ObjectPtr &outres, rabbit::Bool raiseerror,ExecutionType et)
|
bool rabbit::VirtualMachine::execute(rabbit::ObjectPtr &closure, int64_t nargs, int64_t stackbase,rabbit::ObjectPtr &outres, rabbit::Bool raiseerror,ExecutionType et)
|
||||||
{
|
{
|
||||||
@ -727,16 +759,23 @@ exception_restore:
|
|||||||
//printf("\n[%d] %s %d %d %d %d\n",ci->_ip-ci->_closure.toClosure()->_function->_instructions,g_InstrDesc[_i_.op].name,arg0,arg1,arg2,arg3);
|
//printf("\n[%d] %s %d %d %d %d\n",ci->_ip-ci->_closure.toClosure()->_function->_instructions,g_InstrDesc[_i_.op].name,arg0,arg1,arg2,arg3);
|
||||||
switch(_i_.op)
|
switch(_i_.op)
|
||||||
{
|
{
|
||||||
case _OP_LINE: if (_debughook) callDebugHook('l',arg1); continue;
|
case _OP_LINE:
|
||||||
case _OP_LOAD: TARGET = ci->_literals[arg1]; continue;
|
if (_debughook) {
|
||||||
|
callDebugHook('l',arg1);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
case _OP_LOAD:
|
||||||
|
TARGET = ci->_literals[arg1];
|
||||||
|
continue;
|
||||||
case _OP_LOADINT:
|
case _OP_LOADINT:
|
||||||
TARGET = (int64_t)((int32_t)arg1); continue;
|
TARGET = (int64_t)((int32_t)arg1);
|
||||||
|
continue;
|
||||||
case _OP_LOADFLOAT: TARGET = *((const float_t *)&arg1); continue;
|
case _OP_LOADFLOAT: TARGET = *((const float_t *)&arg1); continue;
|
||||||
case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue;
|
case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue;
|
||||||
case _OP_TAILCALL:{
|
case _OP_TAILCALL:{
|
||||||
rabbit::ObjectPtr &t = STK(arg1);
|
rabbit::ObjectPtr &t = STK(arg1);
|
||||||
if (sq_type(t) == rabbit::OT_CLOSURE
|
if ( t.isClosure() == true
|
||||||
&& (!t.toClosure()->_function->_bgenerator)){
|
&& !t.toClosure()->_function->_bgenerator ){
|
||||||
rabbit::ObjectPtr clo = t;
|
rabbit::ObjectPtr clo = t;
|
||||||
int64_t last_top = _top;
|
int64_t last_top = _top;
|
||||||
if(_openouters) closeOuters(&(_stack[_stackbase]));
|
if(_openouters) closeOuters(&(_stack[_stackbase]));
|
||||||
@ -750,70 +789,73 @@ exception_restore:
|
|||||||
}
|
}
|
||||||
case _OP_CALL: {
|
case _OP_CALL: {
|
||||||
rabbit::ObjectPtr clo = STK(arg1);
|
rabbit::ObjectPtr clo = STK(arg1);
|
||||||
switch (sq_type(clo)) {
|
switch (clo.getType()) {
|
||||||
case rabbit::OT_CLOSURE:
|
case rabbit::OT_CLOSURE:
|
||||||
_GUARD(startcall(clo.toClosure(), sarg0, arg3, _stackbase+arg2, false));
|
_GUARD(startcall(clo.toClosure(), sarg0, arg3, _stackbase+arg2, false));
|
||||||
continue;
|
continue;
|
||||||
case rabbit::OT_NATIVECLOSURE: {
|
case rabbit::OT_NATIVECLOSURE:
|
||||||
bool suspend;
|
{
|
||||||
bool tailcall;
|
bool suspend;
|
||||||
_GUARD(callNative(clo.toNativeClosure(), arg3, _stackbase+arg2, clo, (int32_t)sarg0, suspend, tailcall));
|
bool tailcall;
|
||||||
if(suspend){
|
_GUARD(callNative(clo.toNativeClosure(), arg3, _stackbase+arg2, clo, (int32_t)sarg0, suspend, tailcall));
|
||||||
_suspended = SQTrue;
|
if(suspend){
|
||||||
_suspended_target = sarg0;
|
_suspended = SQTrue;
|
||||||
_suspended_root = ci->_root;
|
_suspended_target = sarg0;
|
||||||
_suspended_traps = traps;
|
_suspended_root = ci->_root;
|
||||||
outres = clo;
|
_suspended_traps = traps;
|
||||||
return true;
|
outres = clo;
|
||||||
}
|
return true;
|
||||||
if(sarg0 != -1 && !tailcall) {
|
}
|
||||||
STK(arg0) = clo;
|
if(sarg0 != -1 && !tailcall) {
|
||||||
}
|
STK(arg0) = clo;
|
||||||
}
|
}
|
||||||
continue;
|
}
|
||||||
case rabbit::OT_CLASS:{
|
continue;
|
||||||
rabbit::ObjectPtr inst;
|
case rabbit::OT_CLASS:
|
||||||
_GUARD(createClassInstance(clo.toClass(),inst,clo));
|
{
|
||||||
if(sarg0 != -1) {
|
rabbit::ObjectPtr inst;
|
||||||
STK(arg0) = inst;
|
_GUARD(createClassInstance(clo.toClass(),inst,clo));
|
||||||
}
|
if(sarg0 != -1) {
|
||||||
int64_t stkbase;
|
STK(arg0) = inst;
|
||||||
switch(sq_type(clo)) {
|
}
|
||||||
case rabbit::OT_CLOSURE:
|
int64_t stkbase;
|
||||||
stkbase = _stackbase+arg2;
|
switch(clo.getType()) {
|
||||||
_stack[stkbase] = inst;
|
case rabbit::OT_CLOSURE:
|
||||||
_GUARD(startcall(clo.toClosure(), -1, arg3, stkbase, false));
|
stkbase = _stackbase+arg2;
|
||||||
break;
|
_stack[stkbase] = inst;
|
||||||
case rabbit::OT_NATIVECLOSURE:
|
_GUARD(startcall(clo.toClosure(), -1, arg3, stkbase, false));
|
||||||
bool dummy;
|
break;
|
||||||
stkbase = _stackbase+arg2;
|
case rabbit::OT_NATIVECLOSURE:
|
||||||
_stack[stkbase] = inst;
|
bool dummy;
|
||||||
_GUARD(callNative(clo.toNativeClosure(), arg3, stkbase, clo, -1, dummy, dummy));
|
stkbase = _stackbase+arg2;
|
||||||
break;
|
_stack[stkbase] = inst;
|
||||||
default: break; //shutup GCC 4.x
|
_GUARD(callNative(clo.toNativeClosure(), arg3, stkbase, clo, -1, dummy, dummy));
|
||||||
}
|
break;
|
||||||
}
|
default:
|
||||||
break;
|
break; //shutup GCC 4.x
|
||||||
case rabbit::OT_TABLE:
|
}
|
||||||
case rabbit::OT_USERDATA:
|
|
||||||
case rabbit::OT_INSTANCE:{
|
|
||||||
rabbit::ObjectPtr closure;
|
|
||||||
if(clo.toDelegable()->_delegate && clo.toDelegable()->getMetaMethod(this,MT_CALL,closure)) {
|
|
||||||
push(clo);
|
|
||||||
for (int64_t i = 0; i < arg3; i++) push(STK(arg2 + i));
|
|
||||||
if(!callMetaMethod(closure, MT_CALL, arg3+1, clo)) SQ_THROW();
|
|
||||||
if(sarg0 != -1) {
|
|
||||||
STK(arg0) = clo;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
case rabbit::OT_TABLE:
|
||||||
|
case rabbit::OT_USERDATA:
|
||||||
//raise_error("attempt to call '%s'", getTypeName(clo));
|
case rabbit::OT_INSTANCE:
|
||||||
//SQ_THROW();
|
{
|
||||||
}
|
rabbit::ObjectPtr closure;
|
||||||
default:
|
if(clo.toDelegable()->_delegate && clo.toDelegable()->getMetaMethod(this,MT_CALL,closure)) {
|
||||||
raise_error("attempt to call '%s'", getTypeName(clo));
|
push(clo);
|
||||||
SQ_THROW();
|
for (int64_t i = 0; i < arg3; i++) push(STK(arg2 + i));
|
||||||
|
if(!callMetaMethod(closure, MT_CALL, arg3+1, clo)) SQ_THROW();
|
||||||
|
if(sarg0 != -1) {
|
||||||
|
STK(arg0) = clo;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//raise_error("attempt to call '%s'", getTypeName(clo));
|
||||||
|
//SQ_THROW();
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
raise_error("attempt to call '%s'", getTypeName(clo));
|
||||||
|
SQ_THROW();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@ -876,7 +918,7 @@ exception_restore:
|
|||||||
case _OP_LOADNULLS:{ for(int32_t n=0; n < arg1; n++) STK(arg0+n).Null(); }continue;
|
case _OP_LOADNULLS:{ for(int32_t n=0; n < arg1; n++) STK(arg0+n).Null(); }continue;
|
||||||
case _OP_LOADROOT: {
|
case _OP_LOADROOT: {
|
||||||
rabbit::WeakRef *w = ci->_closure.toClosure()->_root;
|
rabbit::WeakRef *w = ci->_closure.toClosure()->_root;
|
||||||
if(sq_type(w->_obj) != rabbit::OT_NULL) {
|
if(w->_obj.isNull() == false) {
|
||||||
TARGET = w->_obj;
|
TARGET = w->_obj;
|
||||||
} else {
|
} else {
|
||||||
TARGET = _roottable; //shoud this be like this? or null
|
TARGET = _roottable; //shoud this be like this? or null
|
||||||
@ -940,40 +982,42 @@ exception_restore:
|
|||||||
}
|
}
|
||||||
STK(arg0).toArray()->append(val); continue;
|
STK(arg0).toArray()->append(val); continue;
|
||||||
}
|
}
|
||||||
case _OP_COMPARITH: {
|
case _OP_COMPARITH:
|
||||||
int64_t selfidx = (((uint64_t)arg1&0xFFFF0000)>>16);
|
{
|
||||||
_GUARD(derefInc(arg3, TARGET, STK(selfidx), STK(arg2), STK(arg1&0x0000FFFF), false, selfidx));
|
int64_t selfidx = (((uint64_t)arg1&0xFFFF0000)>>16);
|
||||||
}
|
_GUARD(derefInc(arg3, TARGET, STK(selfidx), STK(arg2), STK(arg1&0x0000FFFF), false, selfidx));
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
case _OP_INC: {rabbit::ObjectPtr o(sarg3); _GUARD(derefInc('+',TARGET, STK(arg1), STK(arg2), o, false, arg1));} continue;
|
case _OP_INC: {rabbit::ObjectPtr o(sarg3); _GUARD(derefInc('+',TARGET, STK(arg1), STK(arg2), o, false, arg1));} continue;
|
||||||
case _OP_INCL: {
|
case _OP_INCL:
|
||||||
rabbit::ObjectPtr &a = STK(arg1);
|
{
|
||||||
if(sq_type(a) == rabbit::OT_INTEGER) {
|
rabbit::ObjectPtr &a = STK(arg1);
|
||||||
a._unVal.nInteger = a.toInteger() + sarg3;
|
if(a.isInteger() == true) {
|
||||||
|
a._unVal.nInteger = a.toInteger() + sarg3;
|
||||||
|
} else {
|
||||||
|
rabbit::ObjectPtr o(sarg3); //_GUARD(LOCAL_INC('+',TARGET, STK(arg1), o));
|
||||||
|
_ARITH_(+,a,a,o);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
continue;
|
||||||
rabbit::ObjectPtr o(sarg3); //_GUARD(LOCAL_INC('+',TARGET, STK(arg1), o));
|
|
||||||
_ARITH_(+,a,a,o);
|
|
||||||
}
|
|
||||||
} continue;
|
|
||||||
case _OP_PINC: {rabbit::ObjectPtr o(sarg3); _GUARD(derefInc('+',TARGET, STK(arg1), STK(arg2), o, true, arg1));} continue;
|
case _OP_PINC: {rabbit::ObjectPtr o(sarg3); _GUARD(derefInc('+',TARGET, STK(arg1), STK(arg2), o, true, arg1));} continue;
|
||||||
case _OP_PINCL: {
|
case _OP_PINCL:
|
||||||
rabbit::ObjectPtr &a = STK(arg1);
|
{
|
||||||
if(sq_type(a) == rabbit::OT_INTEGER) {
|
rabbit::ObjectPtr &a = STK(arg1);
|
||||||
TARGET = a;
|
if(a.isInteger() == true) {
|
||||||
a._unVal.nInteger = a.toInteger() + sarg3;
|
TARGET = a;
|
||||||
|
a._unVal.nInteger = a.toInteger() + sarg3;
|
||||||
|
} else {
|
||||||
|
rabbit::ObjectPtr o(sarg3); _GUARD(PLOCAL_INC('+',TARGET, STK(arg1), o));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
continue;
|
||||||
rabbit::ObjectPtr o(sarg3); _GUARD(PLOCAL_INC('+',TARGET, STK(arg1), o));
|
|
||||||
}
|
|
||||||
|
|
||||||
} continue;
|
|
||||||
case _OP_CMP: _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg1),TARGET)) 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, GET_FLAG_DO_NOT_RAISE_ERROR | GET_FLAG_RAW, DONT_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:
|
case _OP_INSTANCEOF:
|
||||||
if(sq_type(STK(arg1)) != rabbit::OT_CLASS)
|
if(STK(arg1).isClass() == false)
|
||||||
{raise_error("cannot apply instanceof between a %s and a %s",getTypeName(STK(arg1)),getTypeName(STK(arg2))); SQ_THROW();}
|
{raise_error("cannot apply instanceof between a %s and a %s",getTypeName(STK(arg1)),getTypeName(STK(arg2))); SQ_THROW();}
|
||||||
TARGET = (sq_type(STK(arg2)) == rabbit::OT_INSTANCE) ? (STK(arg2).toInstance()->instanceOf(STK(arg1).toClass())?true:false) : false;
|
TARGET = (STK(arg2).isInstance() == true) ? (STK(arg2).toInstance()->instanceOf(STK(arg1).toClass())?true:false) : false;
|
||||||
continue;
|
continue;
|
||||||
case _OP_AND:
|
case _OP_AND:
|
||||||
if(IsFalse(STK(arg2))) {
|
if(IsFalse(STK(arg2))) {
|
||||||
@ -990,7 +1034,7 @@ exception_restore:
|
|||||||
case _OP_NEG: _GUARD(NEG_OP(TARGET,STK(arg1))); continue;
|
case _OP_NEG: _GUARD(NEG_OP(TARGET,STK(arg1))); continue;
|
||||||
case _OP_NOT: TARGET = IsFalse(STK(arg1)); continue;
|
case _OP_NOT: TARGET = IsFalse(STK(arg1)); continue;
|
||||||
case _OP_BWNOT:
|
case _OP_BWNOT:
|
||||||
if(sq_type(STK(arg1)) == rabbit::OT_INTEGER) {
|
if(STK(arg1).isInteger() == true) {
|
||||||
int64_t t = STK(arg1).toInteger();
|
int64_t t = STK(arg1).toInteger();
|
||||||
TARGET = int64_t(~t);
|
TARGET = int64_t(~t);
|
||||||
continue;
|
continue;
|
||||||
@ -1020,7 +1064,10 @@ exception_restore:
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
case _OP_RESUME:
|
case _OP_RESUME:
|
||||||
if(sq_type(STK(arg1)) != rabbit::OT_GENERATOR){ raise_error("trying to resume a '%s',only genenerator can be resumed", getTypeName(STK(arg1))); SQ_THROW();}
|
if(STK(arg1).isGenerator() == false) {
|
||||||
|
raise_error("trying to resume a '%s',only genenerator can be resumed", getTypeName(STK(arg1)));
|
||||||
|
SQ_THROW();
|
||||||
|
}
|
||||||
_GUARD(STK(arg1).toGenerator()->resume(this, TARGET));
|
_GUARD(STK(arg1).toGenerator()->resume(this, TARGET));
|
||||||
traps += ci->_etraps;
|
traps += ci->_etraps;
|
||||||
continue;
|
continue;
|
||||||
@ -1029,7 +1076,7 @@ exception_restore:
|
|||||||
ci->_ip += tojump; }
|
ci->_ip += tojump; }
|
||||||
continue;
|
continue;
|
||||||
case _OP_POSTFOREACH:
|
case _OP_POSTFOREACH:
|
||||||
assert(sq_type(STK(arg0)) == rabbit::OT_GENERATOR);
|
assert(STK(arg0).isGenerator() == true);
|
||||||
if(STK(arg0).toGenerator()->_state == rabbit::Generator::eDead)
|
if(STK(arg0).toGenerator()->_state == rabbit::Generator::eDead)
|
||||||
ci->_ip += (sarg1 - 1);
|
ci->_ip += (sarg1 - 1);
|
||||||
continue;
|
continue;
|
||||||
@ -1119,7 +1166,7 @@ bool rabbit::VirtualMachine::createClassInstance(rabbit::Class *theclass, rabbit
|
|||||||
|
|
||||||
void rabbit::VirtualMachine::callerrorHandler(rabbit::ObjectPtr &error)
|
void rabbit::VirtualMachine::callerrorHandler(rabbit::ObjectPtr &error)
|
||||||
{
|
{
|
||||||
if(sq_type(_errorhandler) != rabbit::OT_NULL) {
|
if(_errorhandler.isNull() == false) {
|
||||||
rabbit::ObjectPtr out;
|
rabbit::ObjectPtr out;
|
||||||
push(_roottable); push(error);
|
push(_roottable); push(error);
|
||||||
call(_errorhandler, 2, _top-2, out,SQFalse);
|
call(_errorhandler, 2, _top-2, out,SQFalse);
|
||||||
@ -1133,8 +1180,14 @@ void rabbit::VirtualMachine::callDebugHook(int64_t type,int64_t forcedline)
|
|||||||
_debughook = false;
|
_debughook = false;
|
||||||
rabbit::FunctionProto *func=ci->_closure.toClosure()->_function;
|
rabbit::FunctionProto *func=ci->_closure.toClosure()->_function;
|
||||||
if(_debughook_native) {
|
if(_debughook_native) {
|
||||||
const char *src = sq_type(func->_sourcename) == rabbit::OT_STRING?_stringval(func->_sourcename):NULL;
|
const char* src = nullptr;
|
||||||
const char *fname = sq_type(func->_name) == rabbit::OT_STRING?_stringval(func->_name):NULL;
|
if (func->_sourcename.isString() == true) {
|
||||||
|
src = _stringval(func->_sourcename);
|
||||||
|
}
|
||||||
|
const char* fname = nullptr;
|
||||||
|
if (func->_name.isString() == true) {
|
||||||
|
fname = _stringval(func->_name);
|
||||||
|
}
|
||||||
int64_t line = forcedline?forcedline:func->getLine(ci->_ip);
|
int64_t line = forcedline?forcedline:func->getLine(ci->_ip);
|
||||||
_debughook_native(this,type,src,line,fname);
|
_debughook_native(this,type,src,line,fname);
|
||||||
}
|
}
|
||||||
@ -1173,8 +1226,8 @@ bool rabbit::VirtualMachine::callNative(rabbit::NativeClosure *nclosure, int64_t
|
|||||||
etk::Vector<int64_t> &tc = nclosure->_typecheck;
|
etk::Vector<int64_t> &tc = nclosure->_typecheck;
|
||||||
if((tcs = tc.size())) {
|
if((tcs = tc.size())) {
|
||||||
for(int64_t i = 0; i < nargs && i < tcs; i++) {
|
for(int64_t i = 0; i < nargs && i < tcs; i++) {
|
||||||
if((tc[i] != -1) && !(sq_type(_stack[newbase+i]) & tc[i])) {
|
if((tc[i] != -1) && !(_stack[newbase+i].getType() & tc[i])) {
|
||||||
raise_ParamTypeerror(i,tc[i], sq_type(_stack[newbase+i]));
|
raise_ParamTypeerror(i,tc[i], _stack[newbase+i].getType());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1243,7 +1296,7 @@ bool rabbit::VirtualMachine::tailcall(rabbit::Closure *closure, int64_t parambas
|
|||||||
#define FALLBACK_ERROR 2
|
#define FALLBACK_ERROR 2
|
||||||
|
|
||||||
bool rabbit::VirtualMachine::get(const rabbit::ObjectPtr &self, const rabbit::ObjectPtr &key, rabbit::ObjectPtr &dest, uint64_t getflags, int64_t selfidx) {
|
bool rabbit::VirtualMachine::get(const rabbit::ObjectPtr &self, const rabbit::ObjectPtr &key, rabbit::ObjectPtr &dest, uint64_t getflags, int64_t selfidx) {
|
||||||
switch(sq_type(self)){
|
switch(self.getType()){
|
||||||
case rabbit::OT_TABLE:
|
case rabbit::OT_TABLE:
|
||||||
if(self.toTable()->get(key,dest)) {
|
if(self.toTable()->get(key,dest)) {
|
||||||
return true;
|
return true;
|
||||||
@ -1302,11 +1355,11 @@ bool rabbit::VirtualMachine::get(const rabbit::ObjectPtr &self, const rabbit::Ob
|
|||||||
//#ifdef ROrabbit::OT_FALLBACK
|
//#ifdef ROrabbit::OT_FALLBACK
|
||||||
if(selfidx == 0) {
|
if(selfidx == 0) {
|
||||||
rabbit::WeakRef *w = ci->_closure.toClosure()->_root;
|
rabbit::WeakRef *w = ci->_closure.toClosure()->_root;
|
||||||
if(sq_type(w->_obj) != rabbit::OT_NULL)
|
if(w->_obj.isNull() == false) {
|
||||||
{
|
if(get(*((const rabbit::ObjectPtr *)&w->_obj),key,dest,0,DONT_FALL_BACK)) {
|
||||||
if(get(*((const rabbit::ObjectPtr *)&w->_obj),key,dest,0,DONT_FALL_BACK)) return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
//#endif
|
//#endif
|
||||||
if ((getflags & GET_FLAG_DO_NOT_RAISE_ERROR) == 0) raise_Idxerror(key);
|
if ((getflags & GET_FLAG_DO_NOT_RAISE_ERROR) == 0) raise_Idxerror(key);
|
||||||
@ -1316,7 +1369,7 @@ bool rabbit::VirtualMachine::get(const rabbit::ObjectPtr &self, const rabbit::Ob
|
|||||||
bool rabbit::VirtualMachine::invokeDefaultDelegate(const rabbit::ObjectPtr &self,const rabbit::ObjectPtr &key,rabbit::ObjectPtr &dest)
|
bool rabbit::VirtualMachine::invokeDefaultDelegate(const rabbit::ObjectPtr &self,const rabbit::ObjectPtr &key,rabbit::ObjectPtr &dest)
|
||||||
{
|
{
|
||||||
rabbit::Table *ddel = NULL;
|
rabbit::Table *ddel = NULL;
|
||||||
switch(sq_type(self)) {
|
switch(self.getType()) {
|
||||||
case rabbit::OT_CLASS: ddel = _class_ddel; break;
|
case rabbit::OT_CLASS: ddel = _class_ddel; break;
|
||||||
case rabbit::OT_TABLE: ddel = _table_ddel; break;
|
case rabbit::OT_TABLE: ddel = _table_ddel; break;
|
||||||
case rabbit::OT_ARRAY: ddel = _array_ddel; break;
|
case rabbit::OT_ARRAY: ddel = _array_ddel; break;
|
||||||
@ -1335,7 +1388,7 @@ bool rabbit::VirtualMachine::invokeDefaultDelegate(const rabbit::ObjectPtr &self
|
|||||||
|
|
||||||
int64_t rabbit::VirtualMachine::fallBackGet(const rabbit::ObjectPtr &self,const rabbit::ObjectPtr &key,rabbit::ObjectPtr &dest)
|
int64_t rabbit::VirtualMachine::fallBackGet(const rabbit::ObjectPtr &self,const rabbit::ObjectPtr &key,rabbit::ObjectPtr &dest)
|
||||||
{
|
{
|
||||||
switch(sq_type(self)){
|
switch(self.getType()){
|
||||||
case rabbit::OT_TABLE:
|
case rabbit::OT_TABLE:
|
||||||
case rabbit::OT_USERDATA:
|
case rabbit::OT_USERDATA:
|
||||||
//delegation
|
//delegation
|
||||||
@ -1358,12 +1411,13 @@ int64_t rabbit::VirtualMachine::fallBackGet(const rabbit::ObjectPtr &self,const
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pop(2);
|
pop(2);
|
||||||
if(sq_type(_lasterror) != rabbit::OT_NULL) { //NULL means "clean failure" (not found)
|
if(_lasterror.isNull() == false) {
|
||||||
|
//NULL means "clean failure" (not found)
|
||||||
return FALLBACK_ERROR;
|
return FALLBACK_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: break;//shutup GCC 4.x
|
default: break;//shutup GCC 4.x
|
||||||
}
|
}
|
||||||
@ -1373,7 +1427,7 @@ int64_t rabbit::VirtualMachine::fallBackGet(const rabbit::ObjectPtr &self,const
|
|||||||
|
|
||||||
bool rabbit::VirtualMachine::set(const rabbit::ObjectPtr &self,const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val,int64_t selfidx)
|
bool rabbit::VirtualMachine::set(const rabbit::ObjectPtr &self,const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val,int64_t selfidx)
|
||||||
{
|
{
|
||||||
switch(sq_type(self)){
|
switch(self.getType()){
|
||||||
case rabbit::OT_TABLE:
|
case rabbit::OT_TABLE:
|
||||||
if(self.toTable()->set(key,val)) return true;
|
if(self.toTable()->set(key,val)) return true;
|
||||||
break;
|
break;
|
||||||
@ -1408,7 +1462,7 @@ bool rabbit::VirtualMachine::set(const rabbit::ObjectPtr &self,const rabbit::Obj
|
|||||||
|
|
||||||
int64_t rabbit::VirtualMachine::fallBackSet(const rabbit::ObjectPtr &self,const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val)
|
int64_t rabbit::VirtualMachine::fallBackSet(const rabbit::ObjectPtr &self,const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val)
|
||||||
{
|
{
|
||||||
switch(sq_type(self)) {
|
switch(self.getType()) {
|
||||||
case rabbit::OT_TABLE:
|
case rabbit::OT_TABLE:
|
||||||
if(self.toTable()->_delegate) {
|
if(self.toTable()->_delegate) {
|
||||||
if(set(self.toTable()->_delegate,key,val,DONT_FALL_BACK)) return FALLBACK_OK;
|
if(set(self.toTable()->_delegate,key,val,DONT_FALL_BACK)) return FALLBACK_OK;
|
||||||
@ -1428,12 +1482,13 @@ int64_t rabbit::VirtualMachine::fallBackSet(const rabbit::ObjectPtr &self,const
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pop(3);
|
pop(3);
|
||||||
if(sq_type(_lasterror) != rabbit::OT_NULL) { //NULL means "clean failure" (not found)
|
if(_lasterror.isNull() == false) {
|
||||||
|
//NULL means "clean failure" (not found)
|
||||||
return FALLBACK_ERROR;
|
return FALLBACK_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: break;//shutup GCC 4.x
|
default: break;//shutup GCC 4.x
|
||||||
}
|
}
|
||||||
@ -1445,7 +1500,7 @@ bool rabbit::VirtualMachine::clone(const rabbit::ObjectPtr &self,rabbit::ObjectP
|
|||||||
{
|
{
|
||||||
rabbit::ObjectPtr temp_reg;
|
rabbit::ObjectPtr temp_reg;
|
||||||
rabbit::ObjectPtr newobj;
|
rabbit::ObjectPtr newobj;
|
||||||
switch(sq_type(self)){
|
switch(self.getType()){
|
||||||
case rabbit::OT_TABLE:
|
case rabbit::OT_TABLE:
|
||||||
newobj = self.toTable()->clone();
|
newobj = self.toTable()->clone();
|
||||||
goto cloned_mt;
|
goto cloned_mt;
|
||||||
@ -1473,15 +1528,17 @@ cloned_mt:
|
|||||||
|
|
||||||
bool rabbit::VirtualMachine::newSlotA(const rabbit::ObjectPtr &self,const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val,const rabbit::ObjectPtr &attrs,bool bstatic,bool raw)
|
bool rabbit::VirtualMachine::newSlotA(const rabbit::ObjectPtr &self,const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val,const rabbit::ObjectPtr &attrs,bool bstatic,bool raw)
|
||||||
{
|
{
|
||||||
if(sq_type(self) != rabbit::OT_CLASS) {
|
if(self.isClass() == false) {
|
||||||
raise_error("object must be a class");
|
raise_error("object must be a class");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
rabbit::Class *c = const_cast<rabbit::Class*>(self.toClass());
|
rabbit::Class *c = const_cast<rabbit::Class*>(self.toClass());
|
||||||
if(!raw) {
|
if(!raw) {
|
||||||
rabbit::ObjectPtr &mm = c->_metamethods[MT_NEWMEMBER];
|
rabbit::ObjectPtr &mm = c->_metamethods[MT_NEWMEMBER];
|
||||||
if(sq_type(mm) != rabbit::OT_NULL ) {
|
if(mm.isNull() == false ) {
|
||||||
push(self); push(key); push(val);
|
push(self);
|
||||||
|
push(key);
|
||||||
|
push(val);
|
||||||
push(attrs);
|
push(attrs);
|
||||||
push(bstatic);
|
push(bstatic);
|
||||||
return callMetaMethod(mm,MT_NEWMEMBER,5,temp_reg);
|
return callMetaMethod(mm,MT_NEWMEMBER,5,temp_reg);
|
||||||
@ -1489,7 +1546,7 @@ bool rabbit::VirtualMachine::newSlotA(const rabbit::ObjectPtr &self,const rabbit
|
|||||||
}
|
}
|
||||||
if(!newSlot(self, key, val,bstatic))
|
if(!newSlot(self, key, val,bstatic))
|
||||||
return false;
|
return false;
|
||||||
if(sq_type(attrs) != rabbit::OT_NULL) {
|
if(attrs.isNull() == false) {
|
||||||
c->setAttributes(key,attrs);
|
c->setAttributes(key,attrs);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -1497,8 +1554,11 @@ bool rabbit::VirtualMachine::newSlotA(const rabbit::ObjectPtr &self,const rabbit
|
|||||||
|
|
||||||
bool rabbit::VirtualMachine::newSlot(const rabbit::ObjectPtr &self,const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val,bool bstatic)
|
bool rabbit::VirtualMachine::newSlot(const rabbit::ObjectPtr &self,const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val,bool bstatic)
|
||||||
{
|
{
|
||||||
if(sq_type(key) == rabbit::OT_NULL) { raise_error("null cannot be used as index"); return false; }
|
if(key.isNull() == true) {
|
||||||
switch(sq_type(self)) {
|
raise_error("null cannot be used as index");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
switch(self.getType()) {
|
||||||
case rabbit::OT_TABLE:
|
case rabbit::OT_TABLE:
|
||||||
{
|
{
|
||||||
bool rawcall = true;
|
bool rawcall = true;
|
||||||
@ -1561,7 +1621,7 @@ bool rabbit::VirtualMachine::newSlot(const rabbit::ObjectPtr &self,const rabbit:
|
|||||||
|
|
||||||
bool rabbit::VirtualMachine::deleteSlot(const rabbit::ObjectPtr &self,const rabbit::ObjectPtr &key,rabbit::ObjectPtr &res)
|
bool rabbit::VirtualMachine::deleteSlot(const rabbit::ObjectPtr &self,const rabbit::ObjectPtr &key,rabbit::ObjectPtr &res)
|
||||||
{
|
{
|
||||||
switch(sq_type(self)) {
|
switch(self.getType()) {
|
||||||
case rabbit::OT_TABLE:
|
case rabbit::OT_TABLE:
|
||||||
case rabbit::OT_INSTANCE:
|
case rabbit::OT_INSTANCE:
|
||||||
case rabbit::OT_USERDATA: {
|
case rabbit::OT_USERDATA: {
|
||||||
@ -1573,7 +1633,7 @@ bool rabbit::VirtualMachine::deleteSlot(const rabbit::ObjectPtr &self,const rabb
|
|||||||
return callMetaMethod(closure,MT_DELSLOT,2,res);
|
return callMetaMethod(closure,MT_DELSLOT,2,res);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(sq_type(self) == rabbit::OT_TABLE) {
|
if(self.isTable() == true) {
|
||||||
if(self.toTable()->get(key,t)) {
|
if(self.toTable()->get(key,t)) {
|
||||||
self.toTable()->remove(key);
|
self.toTable()->remove(key);
|
||||||
}
|
}
|
||||||
@ -1602,7 +1662,7 @@ bool rabbit::VirtualMachine::call(rabbit::ObjectPtr &closure,int64_t nparams,int
|
|||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
int64_t prevstackbase = _stackbase;
|
int64_t prevstackbase = _stackbase;
|
||||||
#endif
|
#endif
|
||||||
switch(sq_type(closure)) {
|
switch(closure.getType()) {
|
||||||
case rabbit::OT_CLOSURE:
|
case rabbit::OT_CLOSURE:
|
||||||
return execute(closure, nparams, stackbase, outres, raiseerror);
|
return execute(closure, nparams, stackbase, outres, raiseerror);
|
||||||
break;
|
break;
|
||||||
@ -1616,7 +1676,7 @@ int64_t prevstackbase = _stackbase;
|
|||||||
rabbit::ObjectPtr constr;
|
rabbit::ObjectPtr constr;
|
||||||
rabbit::ObjectPtr temp;
|
rabbit::ObjectPtr temp;
|
||||||
createClassInstance(closure.toClass(),outres,constr);
|
createClassInstance(closure.toClass(),outres,constr);
|
||||||
rabbit::ObjectType ctype = sq_type(constr);
|
rabbit::ObjectType ctype = constr.getType();
|
||||||
if (ctype == rabbit::OT_NATIVECLOSURE || ctype == OT_CLOSURE) {
|
if (ctype == rabbit::OT_NATIVECLOSURE || ctype == OT_CLOSURE) {
|
||||||
_stack[stackbase] = outres;
|
_stack[stackbase] = outres;
|
||||||
return call(constr,nparams,stackbase,temp,raiseerror);
|
return call(constr,nparams,stackbase,temp,raiseerror);
|
||||||
@ -1784,7 +1844,7 @@ void rabbit::VirtualMachine::dumpstack(int64_t stackbase,bool dumpall)
|
|||||||
printf(" ");
|
printf(" ");
|
||||||
}
|
}
|
||||||
printf("[" _PRINT_INT_FMT "]:",n);
|
printf("[" _PRINT_INT_FMT "]:",n);
|
||||||
switch(sq_type(obj)){
|
switch(obj.getType()){
|
||||||
case rabbit::OT_FLOAT: printf("FLOAT %.3f",obj.toFloat());break;
|
case rabbit::OT_FLOAT: printf("FLOAT %.3f",obj.toFloat());break;
|
||||||
case rabbit::OT_INTEGER: printf("INTEGER " _PRINT_INT_FMT,obj.toInteger());break;
|
case rabbit::OT_INTEGER: printf("INTEGER " _PRINT_INT_FMT,obj.toInteger());break;
|
||||||
case rabbit::OT_BOOL: printf("BOOL %s",obj.toInteger()?"true":"false");break;
|
case rabbit::OT_BOOL: printf("BOOL %s",obj.toInteger()?"true":"false");break;
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include <rabbit/squtils.hpp>
|
#include <rabbit/squtils.hpp>
|
||||||
|
|
||||||
void rabbit::WeakRef::release() {
|
void rabbit::WeakRef::release() {
|
||||||
if(ISREFCOUNTED(_obj._type)) {
|
if(_obj.isRefCounted() == true) {
|
||||||
_obj._unVal.pRefCounted->_weakref = null;
|
_obj._unVal.pRefCounted->_weakref = null;
|
||||||
}
|
}
|
||||||
sq_delete(this, WeakRef);
|
sq_delete(this, WeakRef);
|
||||||
|
401
rabbit/sqapi.cpp
401
rabbit/sqapi.cpp
@ -33,7 +33,7 @@
|
|||||||
static bool sq_aux_gettypedarg(rabbit::VirtualMachine* v,int64_t idx,rabbit::ObjectType type,rabbit::ObjectPtr **o)
|
static bool sq_aux_gettypedarg(rabbit::VirtualMachine* v,int64_t idx,rabbit::ObjectType type,rabbit::ObjectPtr **o)
|
||||||
{
|
{
|
||||||
*o = &stack_get(v,idx);
|
*o = &stack_get(v,idx);
|
||||||
if(sq_type(**o) != type){
|
if((*o)->getType() != type){
|
||||||
rabbit::ObjectPtr oval = v->printObjVal(**o);
|
rabbit::ObjectPtr oval = v->printObjVal(**o);
|
||||||
v->raise_error("wrong argument type, expected '%s' got '%.50s'",IdType2Name(type),_stringval(oval));
|
v->raise_error("wrong argument type, expected '%s' got '%.50s'",IdType2Name(type),_stringval(oval));
|
||||||
return false;
|
return false;
|
||||||
@ -174,19 +174,25 @@ void rabbit::sq_notifyallexceptions(rabbit::VirtualMachine* v, rabbit::Bool enab
|
|||||||
|
|
||||||
void rabbit::sq_addref(rabbit::VirtualMachine* v,rabbit::Object *po)
|
void rabbit::sq_addref(rabbit::VirtualMachine* v,rabbit::Object *po)
|
||||||
{
|
{
|
||||||
if(!ISREFCOUNTED(sq_type(*po))) return;
|
if(po->isRefCounted() == false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
__addRef(po->_type,po->_unVal);
|
__addRef(po->_type,po->_unVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t rabbit::sq_getrefcount(rabbit::VirtualMachine* v,rabbit::Object *po)
|
uint64_t rabbit::sq_getrefcount(rabbit::VirtualMachine* v,rabbit::Object *po)
|
||||||
{
|
{
|
||||||
if(!ISREFCOUNTED(sq_type(*po))) return 0;
|
if(po->isRefCounted() == false) {
|
||||||
return po->_unVal.pRefCounted->refCountget();
|
return 0;
|
||||||
|
}
|
||||||
|
return po->_unVal.pRefCounted->refCountget();
|
||||||
}
|
}
|
||||||
|
|
||||||
rabbit::Bool rabbit::sq_release(rabbit::VirtualMachine* v,rabbit::Object *po)
|
rabbit::Bool rabbit::sq_release(rabbit::VirtualMachine* v,rabbit::Object *po)
|
||||||
{
|
{
|
||||||
if(!ISREFCOUNTED(sq_type(*po))) return SQTrue;
|
if(po->isRefCounted() == false) {
|
||||||
|
return SQTrue;
|
||||||
|
}
|
||||||
bool ret = (po->_unVal.pRefCounted->refCountget() <= 1) ? SQTrue : SQFalse;
|
bool ret = (po->_unVal.pRefCounted->refCountget() <= 1) ? SQTrue : SQFalse;
|
||||||
__release(po->_type,po->_unVal);
|
__release(po->_type,po->_unVal);
|
||||||
return ret; //the ret val doesn't work(and cannot be fixed)
|
return ret; //the ret val doesn't work(and cannot be fixed)
|
||||||
@ -194,13 +200,15 @@ rabbit::Bool rabbit::sq_release(rabbit::VirtualMachine* v,rabbit::Object *po)
|
|||||||
|
|
||||||
uint64_t rabbit::sq_getvmrefcount(rabbit::VirtualMachine* SQ_UNUSED_ARG(v), const rabbit::Object *po)
|
uint64_t rabbit::sq_getvmrefcount(rabbit::VirtualMachine* SQ_UNUSED_ARG(v), const rabbit::Object *po)
|
||||||
{
|
{
|
||||||
if (!ISREFCOUNTED(sq_type(*po))) return 0;
|
if(po->isRefCounted() == false) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return po->_unVal.pRefCounted->refCountget();
|
return po->_unVal.pRefCounted->refCountget();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * rabbit::sq_objtostring(const rabbit::Object *o)
|
const char * rabbit::sq_objtostring(const rabbit::Object *o)
|
||||||
{
|
{
|
||||||
if(sq_type(*o) == rabbit::OT_STRING) {
|
if(o->isString() == true) {
|
||||||
return _stringval(*o);
|
return _stringval(*o);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -302,8 +310,9 @@ rabbit::Result rabbit::sq_newclass(rabbit::VirtualMachine* v,rabbit::Bool hasbas
|
|||||||
rabbit::Class *baseclass = NULL;
|
rabbit::Class *baseclass = NULL;
|
||||||
if(hasbase) {
|
if(hasbase) {
|
||||||
rabbit::ObjectPtr &base = stack_get(v,-1);
|
rabbit::ObjectPtr &base = stack_get(v,-1);
|
||||||
if(sq_type(base) != rabbit::OT_CLASS)
|
if(base.isClass() == false) {
|
||||||
return sq_throwerror(v,"invalid base type");
|
return sq_throwerror(v,"invalid base type");
|
||||||
|
}
|
||||||
baseclass = base.toClass();
|
baseclass = base.toClass();
|
||||||
}
|
}
|
||||||
rabbit::Class *newclass = rabbit::Class::create(_get_shared_state(v), baseclass);
|
rabbit::Class *newclass = rabbit::Class::create(_get_shared_state(v), baseclass);
|
||||||
@ -316,8 +325,8 @@ rabbit::Bool rabbit::sq_instanceof(rabbit::VirtualMachine* v)
|
|||||||
{
|
{
|
||||||
rabbit::ObjectPtr &inst = stack_get(v,-1);
|
rabbit::ObjectPtr &inst = stack_get(v,-1);
|
||||||
rabbit::ObjectPtr &cl = stack_get(v,-2);
|
rabbit::ObjectPtr &cl = stack_get(v,-2);
|
||||||
if( sq_type(inst) != rabbit::OT_INSTANCE
|
if( inst.isInstance() == false
|
||||||
|| sq_type(cl) != rabbit::OT_CLASS)
|
|| cl.isClass() == false)
|
||||||
return sq_throwerror(v,"invalid param type");
|
return sq_throwerror(v,"invalid param type");
|
||||||
return inst.toInstance()->instanceOf(cl.toClass())?SQTrue:SQFalse;
|
return inst.toInstance()->instanceOf(cl.toClass())?SQTrue:SQFalse;
|
||||||
}
|
}
|
||||||
@ -413,15 +422,13 @@ void rabbit::sq_newclosure(rabbit::VirtualMachine* v,SQFUNCTION func,uint64_t nf
|
|||||||
rabbit::Result rabbit::sq_getclosureinfo(rabbit::VirtualMachine* v,int64_t idx,uint64_t *nparams,uint64_t *nfreevars)
|
rabbit::Result rabbit::sq_getclosureinfo(rabbit::VirtualMachine* v,int64_t idx,uint64_t *nparams,uint64_t *nfreevars)
|
||||||
{
|
{
|
||||||
rabbit::Object o = stack_get(v, idx);
|
rabbit::Object o = stack_get(v, idx);
|
||||||
if(sq_type(o) == rabbit::OT_CLOSURE) {
|
if(o.isClosure() == true) {
|
||||||
rabbit::Closure *c = o.toClosure();
|
rabbit::Closure *c = o.toClosure();
|
||||||
rabbit::FunctionProto *proto = c->_function;
|
rabbit::FunctionProto *proto = c->_function;
|
||||||
*nparams = (uint64_t)proto->_nparameters;
|
*nparams = (uint64_t)proto->_nparameters;
|
||||||
*nfreevars = (uint64_t)proto->_noutervalues;
|
*nfreevars = (uint64_t)proto->_noutervalues;
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
}
|
} else if(o.isNativeClosure() == true) {
|
||||||
else if(sq_type(o) == rabbit::OT_NATIVECLOSURE)
|
|
||||||
{
|
|
||||||
rabbit::NativeClosure *c = o.toNativeClosure();
|
rabbit::NativeClosure *c = o.toNativeClosure();
|
||||||
*nparams = (uint64_t)c->_nparamscheck;
|
*nparams = (uint64_t)c->_nparamscheck;
|
||||||
*nfreevars = c->_noutervalues;
|
*nfreevars = c->_noutervalues;
|
||||||
@ -477,7 +484,7 @@ rabbit::Result rabbit::sq_bindenv(rabbit::VirtualMachine* v,int64_t idx)
|
|||||||
&& env.isInstance() == false) {
|
&& env.isInstance() == false) {
|
||||||
return sq_throwerror(v,"invalid environment");
|
return sq_throwerror(v,"invalid environment");
|
||||||
}
|
}
|
||||||
rabbit::WeakRef *w = env.toRefCounted()->getWeakRef(sq_type(env));
|
rabbit::WeakRef *w = env.toRefCounted()->getWeakRef(env.getType());
|
||||||
rabbit::ObjectPtr ret;
|
rabbit::ObjectPtr ret;
|
||||||
if(o.isClosure() == true) {
|
if(o.isClosure() == true) {
|
||||||
rabbit::Closure *c = o.toClosure()->clone();
|
rabbit::Closure *c = o.toClosure()->clone();
|
||||||
@ -546,7 +553,7 @@ rabbit::Result rabbit::sq_getclosureroot(rabbit::VirtualMachine* v,int64_t idx)
|
|||||||
rabbit::Result rabbit::sq_clear(rabbit::VirtualMachine* v,int64_t idx)
|
rabbit::Result rabbit::sq_clear(rabbit::VirtualMachine* v,int64_t idx)
|
||||||
{
|
{
|
||||||
rabbit::Object &o=stack_get(v,idx);
|
rabbit::Object &o=stack_get(v,idx);
|
||||||
switch(sq_type(o)) {
|
switch(o.getType()) {
|
||||||
case rabbit::OT_TABLE: o.toTable()->clear(); break;
|
case rabbit::OT_TABLE: o.toTable()->clear(); break;
|
||||||
case rabbit::OT_ARRAY: o.toArray()->resize(0); break;
|
case rabbit::OT_ARRAY: o.toArray()->resize(0); break;
|
||||||
default:
|
default:
|
||||||
@ -642,7 +649,7 @@ void rabbit::sq_push(rabbit::VirtualMachine* v,int64_t idx)
|
|||||||
|
|
||||||
rabbit::ObjectType rabbit::sq_gettype(rabbit::VirtualMachine* v,int64_t idx)
|
rabbit::ObjectType rabbit::sq_gettype(rabbit::VirtualMachine* v,int64_t idx)
|
||||||
{
|
{
|
||||||
return sq_type(stack_get(v, idx));
|
return stack_get(v, idx).getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
rabbit::Result rabbit::sq_typeof(rabbit::VirtualMachine* v,int64_t idx)
|
rabbit::Result rabbit::sq_typeof(rabbit::VirtualMachine* v,int64_t idx)
|
||||||
@ -746,7 +753,7 @@ rabbit::Result rabbit::sq_clone(rabbit::VirtualMachine* v,int64_t idx)
|
|||||||
int64_t rabbit::sq_getsize(rabbit::VirtualMachine* v, int64_t idx)
|
int64_t rabbit::sq_getsize(rabbit::VirtualMachine* v, int64_t idx)
|
||||||
{
|
{
|
||||||
rabbit::ObjectPtr &o = stack_get(v, idx);
|
rabbit::ObjectPtr &o = stack_get(v, idx);
|
||||||
rabbit::ObjectType type = sq_type(o);
|
rabbit::ObjectType type = o.getType();
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case rabbit::OT_STRING: return o.toString()->_len;
|
case rabbit::OT_STRING: return o.toString()->_len;
|
||||||
case rabbit::OT_TABLE: return o.toTable()->countUsed();
|
case rabbit::OT_TABLE: return o.toTable()->countUsed();
|
||||||
@ -779,7 +786,7 @@ rabbit::Result rabbit::sq_getuserdata(rabbit::VirtualMachine* v,int64_t idx,rabb
|
|||||||
rabbit::Result rabbit::sq_settypetag(rabbit::VirtualMachine* v,int64_t idx,rabbit::UserPointer typetag)
|
rabbit::Result rabbit::sq_settypetag(rabbit::VirtualMachine* v,int64_t idx,rabbit::UserPointer typetag)
|
||||||
{
|
{
|
||||||
rabbit::ObjectPtr &o = stack_get(v,idx);
|
rabbit::ObjectPtr &o = stack_get(v,idx);
|
||||||
switch(sq_type(o)) {
|
switch(o.getType()) {
|
||||||
case rabbit::OT_USERDATA:
|
case rabbit::OT_USERDATA:
|
||||||
o.toUserData()->setTypeTag(typetag);
|
o.toUserData()->setTypeTag(typetag);
|
||||||
break;
|
break;
|
||||||
@ -794,7 +801,7 @@ rabbit::Result rabbit::sq_settypetag(rabbit::VirtualMachine* v,int64_t idx,rabbi
|
|||||||
|
|
||||||
rabbit::Result rabbit::sq_getobjtypetag(const rabbit::Object *o,rabbit::UserPointer * typetag)
|
rabbit::Result rabbit::sq_getobjtypetag(const rabbit::Object *o,rabbit::UserPointer * typetag)
|
||||||
{
|
{
|
||||||
switch(sq_type(*o)) {
|
switch(o->getType()) {
|
||||||
case rabbit::OT_INSTANCE: *typetag = o->toInstance()->_class->_typetag; break;
|
case rabbit::OT_INSTANCE: *typetag = o->toInstance()->_class->_typetag; break;
|
||||||
case rabbit::OT_USERDATA: *typetag = o->toUserData()->getTypeTag(); break;
|
case rabbit::OT_USERDATA: *typetag = o->toUserData()->getTypeTag(); break;
|
||||||
case rabbit::OT_CLASS: *typetag = o->toClass()->_typetag; break;
|
case rabbit::OT_CLASS: *typetag = o->toClass()->_typetag; break;
|
||||||
@ -822,7 +829,9 @@ rabbit::Result rabbit::sq_getuserpointer(rabbit::VirtualMachine* v, int64_t idx,
|
|||||||
rabbit::Result rabbit::sq_setinstanceup(rabbit::VirtualMachine* v, int64_t idx, rabbit::UserPointer p)
|
rabbit::Result rabbit::sq_setinstanceup(rabbit::VirtualMachine* v, int64_t idx, rabbit::UserPointer p)
|
||||||
{
|
{
|
||||||
rabbit::ObjectPtr &o = stack_get(v,idx);
|
rabbit::ObjectPtr &o = stack_get(v,idx);
|
||||||
if(sq_type(o) != rabbit::OT_INSTANCE) return sq_throwerror(v,"the object is not a class instance");
|
if(o.isInstance() == false) {
|
||||||
|
return sq_throwerror(v,"the object is not a class instance");
|
||||||
|
}
|
||||||
o.toInstance()->_userpointer = p;
|
o.toInstance()->_userpointer = p;
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
}
|
}
|
||||||
@ -830,8 +839,12 @@ rabbit::Result rabbit::sq_setinstanceup(rabbit::VirtualMachine* v, int64_t idx,
|
|||||||
rabbit::Result rabbit::sq_setclassudsize(rabbit::VirtualMachine* v, int64_t idx, int64_t udsize)
|
rabbit::Result rabbit::sq_setclassudsize(rabbit::VirtualMachine* v, int64_t idx, int64_t udsize)
|
||||||
{
|
{
|
||||||
rabbit::ObjectPtr &o = stack_get(v,idx);
|
rabbit::ObjectPtr &o = stack_get(v,idx);
|
||||||
if(sq_type(o) != rabbit::OT_CLASS) return sq_throwerror(v,"the object is not a class");
|
if(o.isClass() == false) {
|
||||||
if(o.toClass()->_locked) return sq_throwerror(v,"the class is locked");
|
return sq_throwerror(v,"the object is not a class");
|
||||||
|
}
|
||||||
|
if(o.toClass()->_locked) {
|
||||||
|
return sq_throwerror(v,"the class is locked");
|
||||||
|
}
|
||||||
o.toClass()->_udsize = udsize;
|
o.toClass()->_udsize = udsize;
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
}
|
}
|
||||||
@ -840,7 +853,9 @@ rabbit::Result rabbit::sq_setclassudsize(rabbit::VirtualMachine* v, int64_t idx,
|
|||||||
rabbit::Result rabbit::sq_getinstanceup(rabbit::VirtualMachine* v, int64_t idx, rabbit::UserPointer *p,rabbit::UserPointer typetag)
|
rabbit::Result rabbit::sq_getinstanceup(rabbit::VirtualMachine* v, int64_t idx, rabbit::UserPointer *p,rabbit::UserPointer typetag)
|
||||||
{
|
{
|
||||||
rabbit::ObjectPtr &o = stack_get(v,idx);
|
rabbit::ObjectPtr &o = stack_get(v,idx);
|
||||||
if(sq_type(o) != rabbit::OT_INSTANCE) return sq_throwerror(v,"the object is not a class instance");
|
if(o.isInstance() == false) {
|
||||||
|
return sq_throwerror(v,"the object is not a class instance");
|
||||||
|
}
|
||||||
(*p) = o.toInstance()->_userpointer;
|
(*p) = o.toInstance()->_userpointer;
|
||||||
if(typetag != 0) {
|
if(typetag != 0) {
|
||||||
rabbit::Class *cl = o.toInstance()->_class;
|
rabbit::Class *cl = o.toInstance()->_class;
|
||||||
@ -897,9 +912,12 @@ rabbit::Result rabbit::sq_newslot(rabbit::VirtualMachine* v, int64_t idx, rabbit
|
|||||||
{
|
{
|
||||||
sq_aux_paramscheck(v, 3);
|
sq_aux_paramscheck(v, 3);
|
||||||
rabbit::ObjectPtr &self = stack_get(v, idx);
|
rabbit::ObjectPtr &self = stack_get(v, idx);
|
||||||
if(sq_type(self) == rabbit::OT_TABLE || sq_type(self) == rabbit::OT_CLASS) {
|
if( self.isTable() == true
|
||||||
|
|| self.isClass() == true) {
|
||||||
rabbit::ObjectPtr &key = v->getUp(-2);
|
rabbit::ObjectPtr &key = v->getUp(-2);
|
||||||
if(sq_type(key) == rabbit::OT_NULL) return sq_throwerror(v, "null is not a valid key");
|
if(key.isNull() == true) {
|
||||||
|
return sq_throwerror(v, "null is not a valid key");
|
||||||
|
}
|
||||||
v->newSlot(self, key, v->getUp(-1),bstatic?true:false);
|
v->newSlot(self, key, v->getUp(-1),bstatic?true:false);
|
||||||
v->pop(2);
|
v->pop(2);
|
||||||
}
|
}
|
||||||
@ -912,14 +930,19 @@ rabbit::Result rabbit::sq_deleteslot(rabbit::VirtualMachine* v,int64_t idx,rabbi
|
|||||||
rabbit::ObjectPtr *self;
|
rabbit::ObjectPtr *self;
|
||||||
_GETSAFE_OBJ(v, idx, rabbit::OT_TABLE,self);
|
_GETSAFE_OBJ(v, idx, rabbit::OT_TABLE,self);
|
||||||
rabbit::ObjectPtr &key = v->getUp(-1);
|
rabbit::ObjectPtr &key = v->getUp(-1);
|
||||||
if(sq_type(key) == rabbit::OT_NULL) return sq_throwerror(v, "null is not a valid key");
|
if(key.isNull() == true) {
|
||||||
|
return sq_throwerror(v, "null is not a valid key");
|
||||||
|
}
|
||||||
rabbit::ObjectPtr res;
|
rabbit::ObjectPtr res;
|
||||||
if(!v->deleteSlot(*self, key, res)){
|
if(!v->deleteSlot(*self, key, res)){
|
||||||
v->pop();
|
v->pop();
|
||||||
return SQ_ERROR;
|
return SQ_ERROR;
|
||||||
}
|
}
|
||||||
if(pushval) v->getUp(-1) = res;
|
if(pushval) {
|
||||||
else v->pop();
|
v->getUp(-1) = res;
|
||||||
|
} else {
|
||||||
|
v->pop();
|
||||||
|
}
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -937,36 +960,36 @@ rabbit::Result rabbit::sq_rawset(rabbit::VirtualMachine* v,int64_t idx)
|
|||||||
{
|
{
|
||||||
rabbit::ObjectPtr &self = stack_get(v, idx);
|
rabbit::ObjectPtr &self = stack_get(v, idx);
|
||||||
rabbit::ObjectPtr &key = v->getUp(-2);
|
rabbit::ObjectPtr &key = v->getUp(-2);
|
||||||
if(sq_type(key) == rabbit::OT_NULL) {
|
if(key.isNull() == true) {
|
||||||
v->pop(2);
|
v->pop(2);
|
||||||
return sq_throwerror(v, "null key");
|
return sq_throwerror(v, "null key");
|
||||||
}
|
}
|
||||||
switch(sq_type(self)) {
|
switch(self.getType()) {
|
||||||
case rabbit::OT_TABLE:
|
case rabbit::OT_TABLE:
|
||||||
self.toTable()->newSlot(key, v->getUp(-1));
|
self.toTable()->newSlot(key, v->getUp(-1));
|
||||||
v->pop(2);
|
|
||||||
return SQ_OK;
|
|
||||||
break;
|
|
||||||
case rabbit::OT_CLASS:
|
|
||||||
self.toClass()->newSlot(_get_shared_state(v), key, v->getUp(-1),false);
|
|
||||||
v->pop(2);
|
|
||||||
return SQ_OK;
|
|
||||||
break;
|
|
||||||
case rabbit::OT_INSTANCE:
|
|
||||||
if(self.toInstance()->set(key, v->getUp(-1))) {
|
|
||||||
v->pop(2);
|
v->pop(2);
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
}
|
break;
|
||||||
break;
|
case rabbit::OT_CLASS:
|
||||||
case rabbit::OT_ARRAY:
|
self.toClass()->newSlot(_get_shared_state(v), key, v->getUp(-1),false);
|
||||||
if(v->set(self, key, v->getUp(-1),false)) {
|
|
||||||
v->pop(2);
|
v->pop(2);
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
}
|
break;
|
||||||
break;
|
case rabbit::OT_INSTANCE:
|
||||||
default:
|
if(self.toInstance()->set(key, v->getUp(-1))) {
|
||||||
v->pop(2);
|
v->pop(2);
|
||||||
return sq_throwerror(v, "rawset works only on array/table/class and instance");
|
return SQ_OK;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case rabbit::OT_ARRAY:
|
||||||
|
if(v->set(self, key, v->getUp(-1),false)) {
|
||||||
|
v->pop(2);
|
||||||
|
return SQ_OK;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
v->pop(2);
|
||||||
|
return sq_throwerror(v, "rawset works only on array/table/class and instance");
|
||||||
}
|
}
|
||||||
v->raise_Idxerror(v->getUp(-2));return SQ_ERROR;
|
v->raise_Idxerror(v->getUp(-2));return SQ_ERROR;
|
||||||
}
|
}
|
||||||
@ -974,9 +997,13 @@ rabbit::Result rabbit::sq_rawset(rabbit::VirtualMachine* v,int64_t idx)
|
|||||||
rabbit::Result rabbit::sq_newmember(rabbit::VirtualMachine* v,int64_t idx,rabbit::Bool bstatic)
|
rabbit::Result rabbit::sq_newmember(rabbit::VirtualMachine* v,int64_t idx,rabbit::Bool bstatic)
|
||||||
{
|
{
|
||||||
rabbit::ObjectPtr &self = stack_get(v, idx);
|
rabbit::ObjectPtr &self = stack_get(v, idx);
|
||||||
if(sq_type(self) != rabbit::OT_CLASS) return sq_throwerror(v, "new member only works with classes");
|
if(self.isClass() == false) {
|
||||||
|
return sq_throwerror(v, "new member only works with classes");
|
||||||
|
}
|
||||||
rabbit::ObjectPtr &key = v->getUp(-3);
|
rabbit::ObjectPtr &key = v->getUp(-3);
|
||||||
if(sq_type(key) == rabbit::OT_NULL) return sq_throwerror(v, "null key");
|
if(key.isNull() == true) {
|
||||||
|
return sq_throwerror(v, "null key");
|
||||||
|
}
|
||||||
if(!v->newSlotA(self,key,v->getUp(-2),v->getUp(-1),bstatic?true:false,false)) {
|
if(!v->newSlotA(self,key,v->getUp(-2),v->getUp(-1),bstatic?true:false,false)) {
|
||||||
v->pop(3);
|
v->pop(3);
|
||||||
return SQ_ERROR;
|
return SQ_ERROR;
|
||||||
@ -988,9 +1015,13 @@ rabbit::Result rabbit::sq_newmember(rabbit::VirtualMachine* v,int64_t idx,rabbit
|
|||||||
rabbit::Result rabbit::sq_rawnewmember(rabbit::VirtualMachine* v,int64_t idx,rabbit::Bool bstatic)
|
rabbit::Result rabbit::sq_rawnewmember(rabbit::VirtualMachine* v,int64_t idx,rabbit::Bool bstatic)
|
||||||
{
|
{
|
||||||
rabbit::ObjectPtr &self = stack_get(v, idx);
|
rabbit::ObjectPtr &self = stack_get(v, idx);
|
||||||
if(sq_type(self) != rabbit::OT_CLASS) return sq_throwerror(v, "new member only works with classes");
|
if(self.isClass() == false) {
|
||||||
|
return sq_throwerror(v, "new member only works with classes");
|
||||||
|
}
|
||||||
rabbit::ObjectPtr &key = v->getUp(-3);
|
rabbit::ObjectPtr &key = v->getUp(-3);
|
||||||
if(sq_type(key) == rabbit::OT_NULL) return sq_throwerror(v, "null key");
|
if(key.isNull() == true) {
|
||||||
|
return sq_throwerror(v, "null key");
|
||||||
|
}
|
||||||
if(!v->newSlotA(self,key,v->getUp(-2),v->getUp(-1),bstatic?true:false,true)) {
|
if(!v->newSlotA(self,key,v->getUp(-2),v->getUp(-1),bstatic?true:false,true)) {
|
||||||
v->pop(3);
|
v->pop(3);
|
||||||
return SQ_ERROR;
|
return SQ_ERROR;
|
||||||
@ -1003,29 +1034,33 @@ rabbit::Result rabbit::sq_setdelegate(rabbit::VirtualMachine* v,int64_t idx)
|
|||||||
{
|
{
|
||||||
rabbit::ObjectPtr &self = stack_get(v, idx);
|
rabbit::ObjectPtr &self = stack_get(v, idx);
|
||||||
rabbit::ObjectPtr &mt = v->getUp(-1);
|
rabbit::ObjectPtr &mt = v->getUp(-1);
|
||||||
rabbit::ObjectType type = sq_type(self);
|
rabbit::ObjectType type = self.getType();
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case rabbit::OT_TABLE:
|
case rabbit::OT_TABLE:
|
||||||
if(sq_type(mt) == rabbit::OT_TABLE) {
|
if (mt.isTable() == true) {
|
||||||
if(!self.toTable()->setDelegate(mt.toTable())) {
|
if(!self.toTable()->setDelegate(mt.toTable())) {
|
||||||
return sq_throwerror(v, "delagate cycle");
|
return sq_throwerror(v, "delagate cycle");
|
||||||
|
}
|
||||||
|
v->pop();
|
||||||
|
} else if (mt.isNull() == true) {
|
||||||
|
self.toTable()->setDelegate(NULL); v->pop();
|
||||||
|
} else {
|
||||||
|
return sq_aux_invalidtype(v, type);
|
||||||
}
|
}
|
||||||
v->pop();
|
break;
|
||||||
}
|
case rabbit::OT_USERDATA:
|
||||||
else if(sq_type(mt)==rabbit::OT_NULL) {
|
if (mt.isTable() == true) {
|
||||||
self.toTable()->setDelegate(NULL); v->pop(); }
|
self.toUserData()->setDelegate(mt.toTable());
|
||||||
else return sq_aux_invalidtype(v,type);
|
v->pop();
|
||||||
break;
|
} else if (mt.isNull() == true) {
|
||||||
case rabbit::OT_USERDATA:
|
self.toUserData()->setDelegate(NULL); v->pop();
|
||||||
if(sq_type(mt)==rabbit::OT_TABLE) {
|
} else {
|
||||||
self.toUserData()->setDelegate(mt.toTable()); v->pop(); }
|
return sq_aux_invalidtype(v, type);
|
||||||
else if(sq_type(mt)==rabbit::OT_NULL) {
|
}
|
||||||
self.toUserData()->setDelegate(NULL); v->pop(); }
|
break;
|
||||||
else return sq_aux_invalidtype(v, type);
|
default:
|
||||||
break;
|
return sq_aux_invalidtype(v, type);
|
||||||
default:
|
break;
|
||||||
return sq_aux_invalidtype(v, type);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
}
|
}
|
||||||
@ -1050,19 +1085,19 @@ rabbit::Result rabbit::sq_rawdeleteslot(rabbit::VirtualMachine* v,int64_t idx,ra
|
|||||||
rabbit::Result rabbit::sq_getdelegate(rabbit::VirtualMachine* v,int64_t idx)
|
rabbit::Result rabbit::sq_getdelegate(rabbit::VirtualMachine* v,int64_t idx)
|
||||||
{
|
{
|
||||||
rabbit::ObjectPtr &self=stack_get(v,idx);
|
rabbit::ObjectPtr &self=stack_get(v,idx);
|
||||||
switch(sq_type(self)){
|
switch (self.getType()){
|
||||||
case rabbit::OT_TABLE:
|
case rabbit::OT_TABLE:
|
||||||
case rabbit::OT_USERDATA:
|
case rabbit::OT_USERDATA:
|
||||||
if(!self.toDelegable()->_delegate){
|
if (!self.toDelegable()->_delegate) {
|
||||||
v->pushNull();
|
v->pushNull();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
v->push(rabbit::ObjectPtr(self.toDelegable()->_delegate));
|
||||||
break;
|
break;
|
||||||
}
|
default:
|
||||||
v->push(rabbit::ObjectPtr(self.toDelegable()->_delegate));
|
return sq_throwerror(v,"wrong type");
|
||||||
break;
|
|
||||||
default: return sq_throwerror(v,"wrong type"); break;
|
|
||||||
}
|
}
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rabbit::Result rabbit::sq_get(rabbit::VirtualMachine* v,int64_t idx)
|
rabbit::Result rabbit::sq_get(rabbit::VirtualMachine* v,int64_t idx)
|
||||||
@ -1075,38 +1110,38 @@ rabbit::Result rabbit::sq_get(rabbit::VirtualMachine* v,int64_t idx)
|
|||||||
return SQ_ERROR;
|
return SQ_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
rabbit::Result rabbit::sq_rawget(rabbit::VirtualMachine* v,int64_t idx)
|
rabbit::Result rabbit::sq_rawget(rabbit::VirtualMachine* v,int64_t idx) {
|
||||||
{
|
|
||||||
rabbit::ObjectPtr &self=stack_get(v,idx);
|
rabbit::ObjectPtr &self=stack_get(v,idx);
|
||||||
rabbit::ObjectPtr &obj = v->getUp(-1);
|
rabbit::ObjectPtr &obj = v->getUp(-1);
|
||||||
switch(sq_type(self)) {
|
switch(self.getType()) {
|
||||||
case rabbit::OT_TABLE:
|
case rabbit::OT_TABLE:
|
||||||
if(self.toTable()->get(obj,obj))
|
if(self.toTable()->get(obj, obj)) {
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
break;
|
}
|
||||||
case rabbit::OT_CLASS:
|
break;
|
||||||
if(self.toClass()->get(obj,obj))
|
case rabbit::OT_CLASS:
|
||||||
return SQ_OK;
|
if(self.toClass()->get(obj, obj)) {
|
||||||
break;
|
return SQ_OK;
|
||||||
case rabbit::OT_INSTANCE:
|
}
|
||||||
if(self.toInstance()->get(obj,obj))
|
break;
|
||||||
return SQ_OK;
|
case rabbit::OT_INSTANCE:
|
||||||
break;
|
if(self.toInstance()->get(obj, obj)) {
|
||||||
case rabbit::OT_ARRAY:
|
return SQ_OK;
|
||||||
{
|
}
|
||||||
if(obj.isNumeric() == true){
|
break;
|
||||||
if(self.toArray()->get(tointeger(obj),obj)) {
|
case rabbit::OT_ARRAY:
|
||||||
|
if(obj.isNumeric() == true) {
|
||||||
|
if(self.toArray()->get(tointeger(obj), obj)) {
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
v->pop();
|
v->pop();
|
||||||
return sq_throwerror(v,"invalid index type for an array");
|
return sq_throwerror(v,"invalid index type for an array");
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
break;
|
default:
|
||||||
default:
|
v->pop();
|
||||||
v->pop();
|
return sq_throwerror(v,"rawget works only on array/table/instance and class");
|
||||||
return sq_throwerror(v,"rawget works only on array/table/instance and class");
|
|
||||||
}
|
}
|
||||||
v->pop();
|
v->pop();
|
||||||
return sq_throwerror(v,"the index doesn't exist");
|
return sq_throwerror(v,"the index doesn't exist");
|
||||||
@ -1129,9 +1164,10 @@ const char * rabbit::sq_getlocal(rabbit::VirtualMachine* v,uint64_t level,uint64
|
|||||||
stackbase-=ci._prevstkbase;
|
stackbase-=ci._prevstkbase;
|
||||||
}
|
}
|
||||||
rabbit::VirtualMachine::callInfo &ci=v->_callsstack[lvl];
|
rabbit::VirtualMachine::callInfo &ci=v->_callsstack[lvl];
|
||||||
if(sq_type(ci._closure)!=rabbit::OT_CLOSURE)
|
if(ci._closure.isClosure() == false) {
|
||||||
return NULL;
|
return NULL;
|
||||||
rabbit::Closure *c=ci._closure.toClosure();
|
}
|
||||||
|
rabbit::Closure *c = ci._closure.toClosure();
|
||||||
rabbit::FunctionProto *func=c->_function;
|
rabbit::FunctionProto *func=c->_function;
|
||||||
if(func->_noutervalues > (int64_t)idx) {
|
if(func->_noutervalues > (int64_t)idx) {
|
||||||
v->push(*c->_outervalues[idx].toOuter()->_valptr);
|
v->push(*c->_outervalues[idx].toOuter()->_valptr);
|
||||||
@ -1150,7 +1186,8 @@ void rabbit::sq_pushobject(rabbit::VirtualMachine* v,rabbit::Object obj)
|
|||||||
|
|
||||||
void rabbit::sq_resetobject(rabbit::Object *po)
|
void rabbit::sq_resetobject(rabbit::Object *po)
|
||||||
{
|
{
|
||||||
po->_unVal.pUserPointer=NULL;po->_type=rabbit::OT_NULL;
|
po->_unVal.pUserPointer = NULL;
|
||||||
|
po->_type = rabbit::OT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rabbit::Result rabbit::sq_throwerror(rabbit::VirtualMachine* v,const char *err)
|
rabbit::Result rabbit::sq_throwerror(rabbit::VirtualMachine* v,const char *err)
|
||||||
@ -1190,13 +1227,15 @@ rabbit::Result rabbit::sq_reservestack(rabbit::VirtualMachine* v,int64_t nsize)
|
|||||||
|
|
||||||
rabbit::Result rabbit::sq_resume(rabbit::VirtualMachine* v,rabbit::Bool retval,rabbit::Bool raiseerror)
|
rabbit::Result rabbit::sq_resume(rabbit::VirtualMachine* v,rabbit::Bool retval,rabbit::Bool raiseerror)
|
||||||
{
|
{
|
||||||
if (sq_type(v->getUp(-1)) == rabbit::OT_GENERATOR)
|
if (v->getUp(-1).isGenerator() == true) {
|
||||||
{
|
|
||||||
v->pushNull(); //retval
|
v->pushNull(); //retval
|
||||||
if (!v->execute(v->getUp(-2), 0, v->_top, v->getUp(-1), raiseerror, rabbit::VirtualMachine::ET_RESUME_GENERATOR))
|
if (!v->execute(v->getUp(-2), 0, v->_top, v->getUp(-1), raiseerror, rabbit::VirtualMachine::ET_RESUME_GENERATOR)) {
|
||||||
{v->raise_error(v->_lasterror); return SQ_ERROR;}
|
v->raise_error(v->_lasterror);
|
||||||
if(!retval)
|
return SQ_ERROR;
|
||||||
|
}
|
||||||
|
if(!retval) {
|
||||||
v->pop();
|
v->pop();
|
||||||
|
}
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
}
|
}
|
||||||
return sq_throwerror(v,"only generators can be resumed");
|
return sq_throwerror(v,"only generators can be resumed");
|
||||||
@ -1227,7 +1266,7 @@ rabbit::Result rabbit::sq_call(rabbit::VirtualMachine* v,int64_t params,rabbit::
|
|||||||
rabbit::Result rabbit::sq_tailcall(rabbit::VirtualMachine* v, int64_t nparams)
|
rabbit::Result rabbit::sq_tailcall(rabbit::VirtualMachine* v, int64_t nparams)
|
||||||
{
|
{
|
||||||
rabbit::ObjectPtr &res = v->getUp(-(nparams + 1));
|
rabbit::ObjectPtr &res = v->getUp(-(nparams + 1));
|
||||||
if (sq_type(res) != rabbit::OT_CLOSURE) {
|
if (res.isClosure() == false) {
|
||||||
return sq_throwerror(v, "only closure can be tail called");
|
return sq_throwerror(v, "only closure can be tail called");
|
||||||
}
|
}
|
||||||
rabbit::Closure *clo = res.toClosure();
|
rabbit::Closure *clo = res.toClosure();
|
||||||
@ -1273,7 +1312,7 @@ rabbit::Result rabbit::sq_wakeupvm(rabbit::VirtualMachine* v,rabbit::Bool wakeup
|
|||||||
void rabbit::sq_setreleasehook(rabbit::VirtualMachine* v,int64_t idx,SQRELEASEHOOK hook)
|
void rabbit::sq_setreleasehook(rabbit::VirtualMachine* v,int64_t idx,SQRELEASEHOOK hook)
|
||||||
{
|
{
|
||||||
rabbit::ObjectPtr &ud=stack_get(v,idx);
|
rabbit::ObjectPtr &ud=stack_get(v,idx);
|
||||||
switch(sq_type(ud) ) {
|
switch (ud.getType()) {
|
||||||
case rabbit::OT_USERDATA:
|
case rabbit::OT_USERDATA:
|
||||||
ud.toUserData()->setHook(hook);
|
ud.toUserData()->setHook(hook);
|
||||||
break;
|
break;
|
||||||
@ -1291,7 +1330,7 @@ void rabbit::sq_setreleasehook(rabbit::VirtualMachine* v,int64_t idx,SQRELEASEHO
|
|||||||
SQRELEASEHOOK rabbit::sq_getreleasehook(rabbit::VirtualMachine* v,int64_t idx)
|
SQRELEASEHOOK rabbit::sq_getreleasehook(rabbit::VirtualMachine* v,int64_t idx)
|
||||||
{
|
{
|
||||||
rabbit::ObjectPtr &ud=stack_get(v,idx);
|
rabbit::ObjectPtr &ud=stack_get(v,idx);
|
||||||
switch(sq_type(ud) ) {
|
switch (ud.getType()) {
|
||||||
case rabbit::OT_USERDATA:
|
case rabbit::OT_USERDATA:
|
||||||
return ud.toUserData()->getHook();
|
return ud.toUserData()->getHook();
|
||||||
break;
|
break;
|
||||||
@ -1370,27 +1409,29 @@ const char * rabbit::sq_getfreevariable(rabbit::VirtualMachine* v,int64_t idx,ui
|
|||||||
{
|
{
|
||||||
rabbit::ObjectPtr &self=stack_get(v,idx);
|
rabbit::ObjectPtr &self=stack_get(v,idx);
|
||||||
const char *name = NULL;
|
const char *name = NULL;
|
||||||
switch(sq_type(self))
|
switch(self.getType()) {
|
||||||
{
|
case rabbit::OT_CLOSURE:
|
||||||
case rabbit::OT_CLOSURE:{
|
{
|
||||||
rabbit::Closure *clo = self.toClosure();
|
rabbit::Closure *clo = self.toClosure();
|
||||||
rabbit::FunctionProto *fp = clo->_function;
|
rabbit::FunctionProto *fp = clo->_function;
|
||||||
if(((uint64_t)fp->_noutervalues) > nval) {
|
if(((uint64_t)fp->_noutervalues) > nval) {
|
||||||
v->push(*(clo->_outervalues[nval].toOuter()->_valptr));
|
v->push(*(clo->_outervalues[nval].toOuter()->_valptr));
|
||||||
rabbit::OuterVar &ov = fp->_outervalues[nval];
|
rabbit::OuterVar &ov = fp->_outervalues[nval];
|
||||||
name = _stringval(ov._name);
|
name = _stringval(ov._name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case rabbit::OT_NATIVECLOSURE:{
|
case rabbit::OT_NATIVECLOSURE:
|
||||||
rabbit::NativeClosure *clo = self.toNativeClosure();
|
{
|
||||||
if(clo->_noutervalues > nval) {
|
rabbit::NativeClosure *clo = self.toNativeClosure();
|
||||||
v->push(clo->_outervalues[nval]);
|
if(clo->_noutervalues > nval) {
|
||||||
name = "@NATIVE";
|
v->push(clo->_outervalues[nval]);
|
||||||
}
|
name = "@NATIVE";
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
default: break; //shutup compiler
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
@ -1398,24 +1439,26 @@ const char * rabbit::sq_getfreevariable(rabbit::VirtualMachine* v,int64_t idx,ui
|
|||||||
rabbit::Result rabbit::sq_setfreevariable(rabbit::VirtualMachine* v,int64_t idx,uint64_t nval)
|
rabbit::Result rabbit::sq_setfreevariable(rabbit::VirtualMachine* v,int64_t idx,uint64_t nval)
|
||||||
{
|
{
|
||||||
rabbit::ObjectPtr &self=stack_get(v,idx);
|
rabbit::ObjectPtr &self=stack_get(v,idx);
|
||||||
switch(sq_type(self))
|
switch (self.getType()) {
|
||||||
{
|
case rabbit::OT_CLOSURE:
|
||||||
case rabbit::OT_CLOSURE:{
|
{
|
||||||
rabbit::FunctionProto *fp = self.toClosure()->_function;
|
rabbit::FunctionProto *fp = self.toClosure()->_function;
|
||||||
if(((uint64_t)fp->_noutervalues) > nval){
|
if(((uint64_t)fp->_noutervalues) > nval){
|
||||||
*(self.toClosure()->_outervalues[nval].toOuter()->_valptr) = stack_get(v,-1);
|
*(self.toClosure()->_outervalues[nval].toOuter()->_valptr) = stack_get(v,-1);
|
||||||
}
|
} else {
|
||||||
else return sq_throwerror(v,"invalid free var index");
|
return sq_throwerror(v,"invalid free var index");
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case rabbit::OT_NATIVECLOSURE:
|
break;
|
||||||
if(self.toNativeClosure()->_noutervalues > nval){
|
case rabbit::OT_NATIVECLOSURE:
|
||||||
self.toNativeClosure()->_outervalues[nval] = stack_get(v,-1);
|
if(self.toNativeClosure()->_noutervalues > nval) {
|
||||||
}
|
self.toNativeClosure()->_outervalues[nval] = stack_get(v,-1);
|
||||||
else return sq_throwerror(v,"invalid free var index");
|
} else {
|
||||||
break;
|
return sq_throwerror(v,"invalid free var index");
|
||||||
default:
|
}
|
||||||
return sq_aux_invalidtype(v, sq_type(self));
|
break;
|
||||||
|
default:
|
||||||
|
return sq_aux_invalidtype(v, self.getType());
|
||||||
}
|
}
|
||||||
v->pop();
|
v->pop();
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
@ -1428,13 +1471,13 @@ rabbit::Result rabbit::sq_setattributes(rabbit::VirtualMachine* v,int64_t idx)
|
|||||||
rabbit::ObjectPtr &key = stack_get(v,-2);
|
rabbit::ObjectPtr &key = stack_get(v,-2);
|
||||||
rabbit::ObjectPtr &val = stack_get(v,-1);
|
rabbit::ObjectPtr &val = stack_get(v,-1);
|
||||||
rabbit::ObjectPtr attrs;
|
rabbit::ObjectPtr attrs;
|
||||||
if(sq_type(key) == rabbit::OT_NULL) {
|
if(key.isNull() == true) {
|
||||||
attrs = o->toClass()->_attributes;
|
attrs = o->toClass()->_attributes;
|
||||||
o->toClass()->_attributes = val;
|
o->toClass()->_attributes = val;
|
||||||
v->pop(2);
|
v->pop(2);
|
||||||
v->push(attrs);
|
v->push(attrs);
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
}else if(o->toClass()->getAttributes(key,attrs)) {
|
} else if(o->toClass()->getAttributes(key,attrs)) {
|
||||||
o->toClass()->setAttributes(key,val);
|
o->toClass()->setAttributes(key,val);
|
||||||
v->pop(2);
|
v->pop(2);
|
||||||
v->push(attrs);
|
v->push(attrs);
|
||||||
@ -1449,13 +1492,13 @@ rabbit::Result rabbit::sq_getattributes(rabbit::VirtualMachine* v,int64_t idx)
|
|||||||
_GETSAFE_OBJ(v, idx, rabbit::OT_CLASS,o);
|
_GETSAFE_OBJ(v, idx, rabbit::OT_CLASS,o);
|
||||||
rabbit::ObjectPtr &key = stack_get(v,-1);
|
rabbit::ObjectPtr &key = stack_get(v,-1);
|
||||||
rabbit::ObjectPtr attrs;
|
rabbit::ObjectPtr attrs;
|
||||||
if(sq_type(key) == rabbit::OT_NULL) {
|
if(key.isNull() == true) {
|
||||||
attrs = o->toClass()->_attributes;
|
attrs = o->toClass()->_attributes;
|
||||||
v->pop();
|
v->pop();
|
||||||
v->push(attrs);
|
v->push(attrs);
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
}
|
}
|
||||||
else if(o->toClass()->getAttributes(key,attrs)) {
|
else if(o->toClass()->getAttributes(key, attrs)) {
|
||||||
v->pop();
|
v->pop();
|
||||||
v->push(attrs);
|
v->push(attrs);
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
@ -1481,25 +1524,24 @@ rabbit::Result rabbit::sq_getmemberhandle(rabbit::VirtualMachine* v,int64_t idx,
|
|||||||
|
|
||||||
rabbit::Result _getmemberbyhandle(rabbit::VirtualMachine* v,rabbit::ObjectPtr &self,const rabbit::MemberHandle *handle,rabbit::ObjectPtr *&val)
|
rabbit::Result _getmemberbyhandle(rabbit::VirtualMachine* v,rabbit::ObjectPtr &self,const rabbit::MemberHandle *handle,rabbit::ObjectPtr *&val)
|
||||||
{
|
{
|
||||||
switch(sq_type(self)) {
|
switch (self.getType()) {
|
||||||
case rabbit::OT_INSTANCE: {
|
case rabbit::OT_INSTANCE:
|
||||||
|
{
|
||||||
rabbit::Instance *i = self.toInstance();
|
rabbit::Instance *i = self.toInstance();
|
||||||
if(handle->_static) {
|
if(handle->_static) {
|
||||||
rabbit::Class *c = i->_class;
|
rabbit::Class *c = i->_class;
|
||||||
val = &c->_methods[handle->_index].val;
|
val = &c->_methods[handle->_index].val;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val = &i->_values[handle->_index];
|
val = &i->_values[handle->_index];
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case rabbit::OT_CLASS: {
|
case rabbit::OT_CLASS:
|
||||||
|
{
|
||||||
rabbit::Class *c = self.toClass();
|
rabbit::Class *c = self.toClass();
|
||||||
if(handle->_static) {
|
if(handle->_static) {
|
||||||
val = &c->_methods[handle->_index].val;
|
val = &c->_methods[handle->_index].val;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val = &c->_defaultvalues[handle->_index].val;
|
val = &c->_defaultvalues[handle->_index].val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1564,8 +1606,8 @@ rabbit::Result rabbit::sq_createinstance(rabbit::VirtualMachine* v,int64_t idx)
|
|||||||
void rabbit::sq_weakref(rabbit::VirtualMachine* v,int64_t idx)
|
void rabbit::sq_weakref(rabbit::VirtualMachine* v,int64_t idx)
|
||||||
{
|
{
|
||||||
rabbit::Object &o=stack_get(v,idx);
|
rabbit::Object &o=stack_get(v,idx);
|
||||||
if(ISREFCOUNTED(sq_type(o))) {
|
if (o.isRefCounted() == true) {
|
||||||
v->push(o.toRefCounted()->getWeakRef(sq_type(o)));
|
v->push(o.toRefCounted()->getWeakRef(o.getType()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
v->push(o);
|
v->push(o);
|
||||||
@ -1574,7 +1616,7 @@ void rabbit::sq_weakref(rabbit::VirtualMachine* v,int64_t idx)
|
|||||||
rabbit::Result rabbit::sq_getweakrefval(rabbit::VirtualMachine* v,int64_t idx)
|
rabbit::Result rabbit::sq_getweakrefval(rabbit::VirtualMachine* v,int64_t idx)
|
||||||
{
|
{
|
||||||
rabbit::ObjectPtr &o = stack_get(v,idx);
|
rabbit::ObjectPtr &o = stack_get(v,idx);
|
||||||
if(sq_type(o) != rabbit::OT_WEAKREF) {
|
if(o.isWeakRef() == false) {
|
||||||
return sq_throwerror(v,"the object must be a weakref");
|
return sq_throwerror(v,"the object must be a weakref");
|
||||||
}
|
}
|
||||||
v->push(o.toWeakRef()->_obj);
|
v->push(o.toWeakRef()->_obj);
|
||||||
@ -1603,13 +1645,14 @@ rabbit::Result rabbit::sq_getdefaultdelegate(rabbit::VirtualMachine* v,rabbit::O
|
|||||||
rabbit::Result rabbit::sq_next(rabbit::VirtualMachine* v,int64_t idx)
|
rabbit::Result rabbit::sq_next(rabbit::VirtualMachine* v,int64_t idx)
|
||||||
{
|
{
|
||||||
rabbit::ObjectPtr o=stack_get(v,idx),&refpos = stack_get(v,-1),realkey,val;
|
rabbit::ObjectPtr o=stack_get(v,idx),&refpos = stack_get(v,-1),realkey,val;
|
||||||
if(sq_type(o) == rabbit::OT_GENERATOR) {
|
if (o.isGenerator() == true) {
|
||||||
return sq_throwerror(v,"cannot iterate a generator");
|
return sq_throwerror(v,"cannot iterate a generator");
|
||||||
}
|
}
|
||||||
int faketojump;
|
int faketojump;
|
||||||
if(!v->FOREACH_OP(o,realkey,val,refpos,0,666,faketojump))
|
if (!v->FOREACH_OP(o,realkey,val,refpos,0,666,faketojump)) {
|
||||||
return SQ_ERROR;
|
return SQ_ERROR;
|
||||||
if(faketojump != 666) {
|
}
|
||||||
|
if (faketojump != 666) {
|
||||||
v->push(realkey);
|
v->push(realkey);
|
||||||
v->push(val);
|
v->push(val);
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
|
@ -176,7 +176,7 @@ static int64_t get_slice_params(rabbit::VirtualMachine* v,int64_t &sidx,int64_t
|
|||||||
o=stack_get(v,1);
|
o=stack_get(v,1);
|
||||||
if(top>1){
|
if(top>1){
|
||||||
rabbit::ObjectPtr &start=stack_get(v,2);
|
rabbit::ObjectPtr &start=stack_get(v,2);
|
||||||
if( sq_type(start)!=rabbit::OT_NULL
|
if( start.isNull() == false
|
||||||
&& start.isNumeric() == true){
|
&& start.isNumeric() == true){
|
||||||
sidx=tointeger(start);
|
sidx=tointeger(start);
|
||||||
}
|
}
|
||||||
@ -344,7 +344,7 @@ static int64_t default_delegate_len(rabbit::VirtualMachine* v)
|
|||||||
static int64_t default_delegate_tofloat(rabbit::VirtualMachine* v)
|
static int64_t default_delegate_tofloat(rabbit::VirtualMachine* v)
|
||||||
{
|
{
|
||||||
rabbit::ObjectPtr &o=stack_get(v,1);
|
rabbit::ObjectPtr &o=stack_get(v,1);
|
||||||
switch(sq_type(o)){
|
switch(o.getType()){
|
||||||
case rabbit::OT_STRING:{
|
case rabbit::OT_STRING:{
|
||||||
rabbit::ObjectPtr res;
|
rabbit::ObjectPtr res;
|
||||||
if(str2num(_stringval(o),res,10)){
|
if(str2num(_stringval(o),res,10)){
|
||||||
@ -374,7 +374,7 @@ static int64_t default_delegate_tointeger(rabbit::VirtualMachine* v)
|
|||||||
if(sq_gettop(v) > 1) {
|
if(sq_gettop(v) > 1) {
|
||||||
sq_getinteger(v,2,&base);
|
sq_getinteger(v,2,&base);
|
||||||
}
|
}
|
||||||
switch(sq_type(o)){
|
switch(o.getType()){
|
||||||
case rabbit::OT_STRING:{
|
case rabbit::OT_STRING:{
|
||||||
rabbit::ObjectPtr res;
|
rabbit::ObjectPtr res;
|
||||||
if(str2num(_stringval(o),res,base)){
|
if(str2num(_stringval(o),res,base)){
|
||||||
@ -933,8 +933,8 @@ static int64_t closure_pcall(rabbit::VirtualMachine* v)
|
|||||||
static int64_t closure_call(rabbit::VirtualMachine* v)
|
static int64_t closure_call(rabbit::VirtualMachine* v)
|
||||||
{
|
{
|
||||||
rabbit::ObjectPtr &c = stack_get(v, -1);
|
rabbit::ObjectPtr &c = stack_get(v, -1);
|
||||||
if (sq_type(c) == rabbit::OT_CLOSURE && (c.toClosure()->_function->_bgenerator == false))
|
if ( c.isClosure() == true
|
||||||
{
|
&& c.toClosure()->_function->_bgenerator == false) {
|
||||||
return sq_tailcall(v, sq_gettop(v) - 1);
|
return sq_tailcall(v, sq_gettop(v) - 1);
|
||||||
}
|
}
|
||||||
return SQ_SUCCEEDED(sq_call(v, sq_gettop(v) - 1, SQTrue, SQTrue)) ? 1 : SQ_ERROR;
|
return SQ_SUCCEEDED(sq_call(v, sq_gettop(v) - 1, SQTrue, SQTrue)) ? 1 : SQ_ERROR;
|
||||||
@ -983,7 +983,7 @@ static int64_t closure_setroot(rabbit::VirtualMachine* v)
|
|||||||
static int64_t closure_getinfos(rabbit::VirtualMachine* v) {
|
static int64_t closure_getinfos(rabbit::VirtualMachine* v) {
|
||||||
rabbit::Object o = stack_get(v,1);
|
rabbit::Object o = stack_get(v,1);
|
||||||
rabbit::Table *res = rabbit::Table::create(_get_shared_state(v),4);
|
rabbit::Table *res = rabbit::Table::create(_get_shared_state(v),4);
|
||||||
if(sq_type(o) == rabbit::OT_CLOSURE) {
|
if(o.isClosure() == true) {
|
||||||
rabbit::FunctionProto *f = o.toClosure()->_function;
|
rabbit::FunctionProto *f = o.toClosure()->_function;
|
||||||
int64_t nparams = f->_nparameters + (f->_varparams?1:0);
|
int64_t nparams = f->_nparameters + (f->_varparams?1:0);
|
||||||
rabbit::ObjectPtr params = rabbit::Array::create(_get_shared_state(v),nparams);
|
rabbit::ObjectPtr params = rabbit::Array::create(_get_shared_state(v),nparams);
|
||||||
@ -1062,7 +1062,7 @@ const rabbit::RegFunction rabbit::SharedState::_generator_default_delegate_funcz
|
|||||||
static int64_t thread_call(rabbit::VirtualMachine* v)
|
static int64_t thread_call(rabbit::VirtualMachine* v)
|
||||||
{
|
{
|
||||||
rabbit::ObjectPtr o = stack_get(v,1);
|
rabbit::ObjectPtr o = stack_get(v,1);
|
||||||
if(sq_type(o) == rabbit::OT_THREAD) {
|
if(o.isVirtualMachine() == true) {
|
||||||
int64_t nparams = sq_gettop(v);
|
int64_t nparams = sq_gettop(v);
|
||||||
o.toVirtualMachine()->push(o.toVirtualMachine()->_roottable);
|
o.toVirtualMachine()->push(o.toVirtualMachine()->_roottable);
|
||||||
for(int64_t i = 2; i<(nparams+1); i++)
|
for(int64_t i = 2; i<(nparams+1); i++)
|
||||||
@ -1081,7 +1081,7 @@ static int64_t thread_call(rabbit::VirtualMachine* v)
|
|||||||
static int64_t thread_wakeup(rabbit::VirtualMachine* v)
|
static int64_t thread_wakeup(rabbit::VirtualMachine* v)
|
||||||
{
|
{
|
||||||
rabbit::ObjectPtr o = stack_get(v,1);
|
rabbit::ObjectPtr o = stack_get(v,1);
|
||||||
if(sq_type(o) == rabbit::OT_THREAD) {
|
if(o.isVirtualMachine() == true) {
|
||||||
rabbit::VirtualMachine *thread = o.toVirtualMachine();
|
rabbit::VirtualMachine *thread = o.toVirtualMachine();
|
||||||
int64_t state = sq_getvmstate(thread);
|
int64_t state = sq_getvmstate(thread);
|
||||||
if(state != SQ_VMSTATE_SUSPENDED) {
|
if(state != SQ_VMSTATE_SUSPENDED) {
|
||||||
@ -1117,7 +1117,7 @@ static int64_t thread_wakeup(rabbit::VirtualMachine* v)
|
|||||||
static int64_t thread_wakeupthrow(rabbit::VirtualMachine* v)
|
static int64_t thread_wakeupthrow(rabbit::VirtualMachine* v)
|
||||||
{
|
{
|
||||||
rabbit::ObjectPtr o = stack_get(v,1);
|
rabbit::ObjectPtr o = stack_get(v,1);
|
||||||
if(sq_type(o) == rabbit::OT_THREAD) {
|
if(o.isVirtualMachine() == true) {
|
||||||
rabbit::VirtualMachine *thread = o.toVirtualMachine();
|
rabbit::VirtualMachine *thread = o.toVirtualMachine();
|
||||||
int64_t state = sq_getvmstate(thread);
|
int64_t state = sq_getvmstate(thread);
|
||||||
if(state != SQ_VMSTATE_SUSPENDED) {
|
if(state != SQ_VMSTATE_SUSPENDED) {
|
||||||
@ -1177,7 +1177,7 @@ static int64_t thread_getstatus(rabbit::VirtualMachine* v)
|
|||||||
static int64_t thread_getstackinfos(rabbit::VirtualMachine* v)
|
static int64_t thread_getstackinfos(rabbit::VirtualMachine* v)
|
||||||
{
|
{
|
||||||
rabbit::ObjectPtr o = stack_get(v,1);
|
rabbit::ObjectPtr o = stack_get(v,1);
|
||||||
if(sq_type(o) == rabbit::OT_THREAD) {
|
if(o.isVirtualMachine() == true) {
|
||||||
rabbit::VirtualMachine *thread = o.toVirtualMachine();
|
rabbit::VirtualMachine *thread = o.toVirtualMachine();
|
||||||
int64_t threadtop = sq_gettop(thread);
|
int64_t threadtop = sq_gettop(thread);
|
||||||
int64_t level;
|
int64_t level;
|
||||||
@ -1186,7 +1186,7 @@ static int64_t thread_getstackinfos(rabbit::VirtualMachine* v)
|
|||||||
if(SQ_FAILED(res))
|
if(SQ_FAILED(res))
|
||||||
{
|
{
|
||||||
sq_settop(thread,threadtop);
|
sq_settop(thread,threadtop);
|
||||||
if(sq_type(thread->_lasterror) == rabbit::OT_STRING) {
|
if(thread->_lasterror.isString() == true) {
|
||||||
sq_throwerror(v,_stringval(thread->_lasterror));
|
sq_throwerror(v,_stringval(thread->_lasterror));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -31,8 +31,16 @@ rabbit::Result rabbit::sq_getfunctioninfo(rabbit::VirtualMachine* v,int64_t leve
|
|||||||
rabbit::Closure *c = ci._closure.toClosure();
|
rabbit::Closure *c = ci._closure.toClosure();
|
||||||
rabbit::FunctionProto *proto = c->_function;
|
rabbit::FunctionProto *proto = c->_function;
|
||||||
fi->funcid = proto;
|
fi->funcid = proto;
|
||||||
fi->name = sq_type(proto->_name) == rabbit::OT_STRING?_stringval(proto->_name):"unknown";
|
if (proto->_name.isString() == true) {
|
||||||
fi->source = sq_type(proto->_sourcename) == rabbit::OT_STRING?_stringval(proto->_sourcename):"unknown";
|
fi->name = _stringval(proto->_name);
|
||||||
|
} else {
|
||||||
|
fi->name = "unknown";
|
||||||
|
}
|
||||||
|
if (proto->_sourcename.isString() == true) {
|
||||||
|
fi->source = _stringval(proto->_sourcename);
|
||||||
|
} else {
|
||||||
|
fi->source = "unknown";
|
||||||
|
}
|
||||||
fi->line = proto->_lineinfos[0]._line;
|
fi->line = proto->_lineinfos[0]._line;
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
}
|
}
|
||||||
@ -46,24 +54,29 @@ rabbit::Result rabbit::sq_stackinfos(rabbit::VirtualMachine* v, int64_t level, r
|
|||||||
if (cssize > level) {
|
if (cssize > level) {
|
||||||
memset(si, 0, sizeof(rabbit::StackInfos));
|
memset(si, 0, sizeof(rabbit::StackInfos));
|
||||||
rabbit::VirtualMachine::callInfo &ci = v->_callsstack[cssize-level-1];
|
rabbit::VirtualMachine::callInfo &ci = v->_callsstack[cssize-level-1];
|
||||||
switch (sq_type(ci._closure)) {
|
switch (ci._closure.getType()) {
|
||||||
case rabbit::OT_CLOSURE:{
|
case rabbit::OT_CLOSURE:
|
||||||
rabbit::FunctionProto *func = ci._closure.toClosure()->_function;
|
{
|
||||||
if (sq_type(func->_name) == rabbit::OT_STRING)
|
rabbit::FunctionProto *func = ci._closure.toClosure()->_function;
|
||||||
si->funcname = _stringval(func->_name);
|
if (func->_name.isString() == true) {
|
||||||
if (sq_type(func->_sourcename) == rabbit::OT_STRING)
|
si->funcname = _stringval(func->_name);
|
||||||
si->source = _stringval(func->_sourcename);
|
}
|
||||||
si->line = func->getLine(ci._ip);
|
if (func->_sourcename.isString() == true) {
|
||||||
}
|
si->source = _stringval(func->_sourcename);
|
||||||
break;
|
}
|
||||||
case rabbit::OT_NATIVECLOSURE:
|
si->line = func->getLine(ci._ip);
|
||||||
si->source = "NATIVE";
|
}
|
||||||
si->funcname = "unknown";
|
break;
|
||||||
if(sq_type(ci._closure.toNativeClosure()->_name) == rabbit::OT_STRING)
|
case rabbit::OT_NATIVECLOSURE:
|
||||||
si->funcname = _stringval(ci._closure.toNativeClosure()->_name);
|
si->source = "NATIVE";
|
||||||
si->line = -1;
|
si->funcname = "unknown";
|
||||||
break;
|
if(ci._closure.toNativeClosure()->_name.isString() == true) {
|
||||||
default: break; //shutup compiler
|
si->funcname = _stringval(ci._closure.toNativeClosure()->_name);
|
||||||
|
}
|
||||||
|
si->line = -1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break; //shutup compiler
|
||||||
}
|
}
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
}
|
}
|
||||||
@ -87,19 +100,19 @@ void rabbit::VirtualMachine::raise_error(const rabbit::ObjectPtr &desc)
|
|||||||
|
|
||||||
rabbit::String *rabbit::VirtualMachine::printObjVal(const rabbit::ObjectPtr &o)
|
rabbit::String *rabbit::VirtualMachine::printObjVal(const rabbit::ObjectPtr &o)
|
||||||
{
|
{
|
||||||
switch(sq_type(o)) {
|
switch(o.getType()) {
|
||||||
case rabbit::OT_STRING:
|
case rabbit::OT_STRING:
|
||||||
return const_cast<rabbit::String *>(o.toString());
|
return const_cast<rabbit::String *>(o.toString());
|
||||||
case rabbit::OT_INTEGER:
|
case rabbit::OT_INTEGER:
|
||||||
snprintf(_sp(sq_rsl(NUMBER_UINT8_MAX+1)),sq_rsl(NUMBER_UINT8_MAX), _PRINT_INT_FMT, o.toInteger());
|
snprintf(_sp(sq_rsl(NUMBER_UINT8_MAX+1)),sq_rsl(NUMBER_UINT8_MAX), _PRINT_INT_FMT, o.toInteger());
|
||||||
return rabbit::String::create(_get_shared_state(this), _spval);
|
return rabbit::String::create(_get_shared_state(this), _spval);
|
||||||
break;
|
break;
|
||||||
case rabbit::OT_FLOAT:
|
case rabbit::OT_FLOAT:
|
||||||
snprintf(_sp(sq_rsl(NUMBER_UINT8_MAX+1)), sq_rsl(NUMBER_UINT8_MAX), "%.14g", o.toFloat());
|
snprintf(_sp(sq_rsl(NUMBER_UINT8_MAX+1)), sq_rsl(NUMBER_UINT8_MAX), "%.14g", o.toFloat());
|
||||||
return rabbit::String::create(_get_shared_state(this), _spval);
|
return rabbit::String::create(_get_shared_state(this), _spval);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return rabbit::String::create(_get_shared_state(this), getTypeName(o));
|
return rabbit::String::create(_get_shared_state(this), getTypeName(o));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user