SQClass::SQClass( SQSharedState *ss, SQClass *base ) { _base = base; _typetag = 0; _metamethods.resize( MT_LAST ); //size it to max size if ( _base ) { _defaultvalues.copy( base->_defaultvalues ); _methods.copy( base->_methods ); _metamethods.copy( base->_metamethods ); __ObjAddRef( _base ); } _members = base ? base->_members->Clone() : SQTable::Create( ss, 0 ); __ObjAddRef( _members ); _locked = false; INIT_CHAIN(); ADD_TO_CHAIN( &_sharedstate->_gc_chain, this ); }
void SQInstance::Init( SQSharedState *ss ) { _userpointer = NULL; _hook = NULL; __ObjAddRef( _class ); _delegate = _class->_members; INIT_CHAIN(); ADD_TO_CHAIN( &_sharedstate->_gc_chain, this ); }
bool SQDelegable::SetDelegate( SQTable *mt ) { SQTable *temp = mt; while ( temp ) { if ( temp->_delegate == this ) return false; //cycle detected temp = temp->_delegate; } if ( mt ) __ObjAddRef( mt ); __ObjRelease( _delegate ); _delegate = mt; return true; }
SQClass::SQClass(SQSharedState *ss,SQClass *base) { _base = base; _typetag = 0; _hook = NULL; _udsize = 0; _locked = false; _constructoridx = -1; if(_base) { _constructoridx = _base->_constructoridx; _udsize = _base->_udsize; _defaultvalues.copy(base->_defaultvalues); _methods.copy(base->_methods); _COPY_VECTOR(_metamethods,base->_metamethods,MT_LAST); __ObjAddRef(_base); } _members = base?base->_members->Clone() : SQTable::Create(ss,0); __ObjAddRef(_members); INIT_CHAIN(); ADD_TO_CHAIN(&_sharedstate->_gc_chain, this); }
bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic) { SQObjectPtr temp; bool belongs_to_static_table = type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE || bstatic; if(_locked && !belongs_to_static_table) return false; //the class already has an instance so cannot be modified if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value { _defaultvalues[_member_idx(temp)].val = val; return true; } if(belongs_to_static_table) { SQInteger mmidx; if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) && (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) { _metamethods[mmidx] = val; } else { SQObjectPtr theval = val; if(_base && type(val) == OT_CLOSURE) { theval = _closure(val)->Clone(); _closure(theval)->_base = _base; __ObjAddRef(_base); //ref for the closure } if(type(temp) == OT_NULL) { bool isconstructor; SQVM::IsEqual(ss->_constructoridx, key, isconstructor); if(isconstructor) { _constructoridx = (SQInteger)_methods.size(); } SQClassMember m; m.val = theval; _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size()))); _methods.push_back(m); } else { _methods[_member_idx(temp)].val = theval; } } return true; } SQClassMember m; m.val = val; _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size()))); _defaultvalues.push_back(m); return true; }