diff --git a/squirrel/sqobject.cpp b/squirrel/sqobject.cpp index 909e6e93..98cdcafa 100644 --- a/squirrel/sqobject.cpp +++ b/squirrel/sqobject.cpp @@ -11,6 +11,31 @@ #include "sqclass.h" #include "sqclosure.h" +const SQChar *SQMetaMethodName[] = { + _SC("_add"), + _SC("_sub"), + _SC("_mul"), + _SC("_div"), + _SC("_unm"), + _SC("_modulo"), + _SC("_set"), + _SC("_get"), + _SC("_typeof"), + _SC("_nexti"), + _SC("_cmp"), + _SC("_call"), + _SC("_cloned"), + _SC("_newslot"), + _SC("_delslot"), + _SC("_tostring"), + _SC("_newmember"), + _SC("_inherited"), + _SC("_shiftl"), + _SC("_shiftr"), + _SC("_and"), + _SC("_or"), + NULL +}; const SQChar *IdType2Name(SQObjectType type) { @@ -46,6 +71,14 @@ const SQChar *GetTypeName(const SQObjectPtr &obj1) return IdType2Name(sq_type(obj1)); } +const SQChar *GetMetaMethodName(SQInteger mmId) +{ + if (mmId SQObjectPtrVec; typedef sqvector SQIntVec; const SQChar *GetTypeName(const SQObjectPtr &obj1); const SQChar *IdType2Name(SQObjectType type); +const SQChar *GetMetaMethodName(SQInteger mmId); diff --git a/squirrel/sqstate.cpp b/squirrel/sqstate.cpp index 91826101..0e489d84 100644 --- a/squirrel/sqstate.cpp +++ b/squirrel/sqstate.cpp @@ -120,24 +120,8 @@ void SQSharedState::Init() newsysstring(_SC("instance")); newsysstring(_SC("bool")); //meta methods - newmetamethod(MM_ADD); - newmetamethod(MM_SUB); - newmetamethod(MM_MUL); - newmetamethod(MM_DIV); - newmetamethod(MM_UNM); - newmetamethod(MM_MODULO); - newmetamethod(MM_SET); - newmetamethod(MM_GET); - newmetamethod(MM_TYPEOF); - newmetamethod(MM_NEXTI); - newmetamethod(MM_CMP); - newmetamethod(MM_CALL); - newmetamethod(MM_CLONED); - newmetamethod(MM_NEWSLOT); - newmetamethod(MM_DELSLOT); - newmetamethod(MM_TOSTRING); - newmetamethod(MM_NEWMEMBER); - newmetamethod(MM_INHERITED); + for (int i=0; i> i2); break; default: { Raise_Error(_SC("internal vm error bitwise op failed")); return false; } } + trg = res; + } + else if( (sq_type(o1) & OT_INSTANCE) ) + { + SQMetaMethod mm; + switch(op) { + case BW_AND: mm = MT_AND; break; + case BW_OR: mm = MT_OR; break; + case BW_SHIFTL: mm = MT_SHIFTL; break; + case BW_SHIFTR: mm = MT_SHIFTR; break; + // add other + default: return false; + } + return ArithMetaMethod(mm,o1,o2,trg); } else { Raise_Error(_SC("bitwise op between '%s' and '%s'"),GetTypeName(o1),GetTypeName(o2)); return false;} - trg = res; + return true; } @@ -100,8 +114,20 @@ bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1, if(op == '+' && (tmask & _RT_STRING)){ if(!StringCat(o1, o2, trg)) return false; } - else if(!ArithMetaMethod(op,o1,o2,trg)) { - return false; + else + { + SQMetaMethod mm; + switch(op) { + case _SC('+'): mm=MT_ADD; break; + case _SC('-'): mm=MT_SUB; break; + case _SC('/'): mm=MT_DIV; break; + case _SC('*'): mm=MT_MUL; break; + case _SC('%'): mm=MT_MODULO; break; + case _SC('&'): mm=MT_AND; break; + case _SC('|'): mm=MT_OR; break; + default: mm=(SQMetaMethod)op; + } + if (!ArithMetaMethod(mm,o1,o2,trg)) return false; } } return true; @@ -151,26 +177,16 @@ SQVM::~SQVM() REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); } -bool SQVM::ArithMetaMethod(SQInteger op,const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &dest) +bool SQVM::ArithMetaMethod(SQMetaMethod mm,const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &dest) { - SQMetaMethod mm; - switch(op){ - case _SC('+'): mm=MT_ADD; break; - case _SC('-'): mm=MT_SUB; break; - case _SC('/'): mm=MT_DIV; break; - case _SC('*'): mm=MT_MUL; break; - case _SC('%'): mm=MT_MODULO; break; - default: mm = MT_ADD; assert(0); break; //shutup compiler - } - if(is_delegable(o1) && _delegable(o1)->_delegate) { - + if(mm>=0 && mm_delegate) { SQObjectPtr closure; if(_delegable(o1)->GetMetaMethod(this, mm, closure)) { Push(o1);Push(o2); return CallMetaMethod(closure,mm,2,dest); } } - Raise_Error(_SC("arith op %c on between '%s' and '%s'"),op,GetTypeName(o1),GetTypeName(o2)); + Raise_Error(_SC("arith op %s on between '%s' and '%s'"), GetMetaMethodName(mm) ,GetTypeName(o1),GetTypeName(o2)); return false; } diff --git a/squirrel/sqvm.h b/squirrel/sqvm.h index 50927507..b185c1a7 100644 --- a/squirrel/sqvm.h +++ b/squirrel/sqvm.h @@ -96,7 +96,7 @@ typedef sqvector CallInfoVec; bool TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest); bool CallMetaMethod(SQObjectPtr &closure, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres); - bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest); + bool ArithMetaMethod(SQMetaMethod mm, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest); bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval); //new stuff _INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);