Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
sqclass.cpp
00001 /* 00002 see copyright notice in squirrel.h 00003 */ 00004 #include "sqpcheader.h" 00005 #include "sqvm.h" 00006 #include "sqtable.h" 00007 #include "sqclass.h" 00008 #include "sqfuncproto.h" 00009 #include "sqclosure.h" 00010 00011 00012 00013 SQClass::SQClass(SQSharedState *ss,SQClass *base) 00014 { 00015 _base = base; 00016 _typetag = 0; 00017 _hook = NULL; 00018 _udsize = 0; 00019 _locked = false; 00020 _constructoridx = -1; 00021 if(_base) { 00022 _constructoridx = _base->_constructoridx; 00023 _udsize = _base->_udsize; 00024 _defaultvalues.copy(base->_defaultvalues); 00025 _methods.copy(base->_methods); 00026 _COPY_VECTOR(_metamethods,base->_metamethods,MT_LAST); 00027 __ObjAddRef(_base); 00028 } 00029 _members = base?base->_members->Clone() : SQTable::Create(ss,0); 00030 __ObjAddRef(_members); 00031 00032 INIT_CHAIN(); 00033 ADD_TO_CHAIN(&_sharedstate->_gc_chain, this); 00034 } 00035 00036 void SQClass::Finalize() { 00037 _attributes.Null(); 00038 _NULL_SQOBJECT_VECTOR(_defaultvalues,_defaultvalues.size()); 00039 _methods.resize(0); 00040 _NULL_SQOBJECT_VECTOR(_metamethods,MT_LAST); 00041 __ObjRelease(_members); 00042 if(_base) { 00043 __ObjRelease(_base); 00044 } 00045 } 00046 00047 SQClass::~SQClass() 00048 { 00049 REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); 00050 Finalize(); 00051 } 00052 00053 bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic) 00054 { 00055 SQObjectPtr temp; 00056 bool belongs_to_static_table = type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE || bstatic; 00057 if(_locked && !belongs_to_static_table) 00058 return false; //the class already has an instance so cannot be modified 00059 if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value 00060 { 00061 _defaultvalues[_member_idx(temp)].val = val; 00062 return true; 00063 } 00064 if(belongs_to_static_table) { 00065 SQInteger mmidx; 00066 if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) && 00067 (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) { 00068 _metamethods[mmidx] = val; 00069 } 00070 else { 00071 SQObjectPtr theval = val; 00072 if(_base && type(val) == OT_CLOSURE) { 00073 theval = _closure(val)->Clone(); 00074 _closure(theval)->_base = _base; 00075 __ObjAddRef(_base); //ref for the closure 00076 } 00077 if(type(temp) == OT_NULL) { 00078 bool isconstructor; 00079 SQVM::IsEqual(ss->_constructoridx, key, isconstructor); 00080 if(isconstructor) { 00081 _constructoridx = (SQInteger)_methods.size(); 00082 } 00083 SQClassMember m; 00084 m.val = theval; 00085 _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size()))); 00086 _methods.push_back(m); 00087 } 00088 else { 00089 _methods[_member_idx(temp)].val = theval; 00090 } 00091 } 00092 return true; 00093 } 00094 SQClassMember m; 00095 m.val = val; 00096 _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size()))); 00097 _defaultvalues.push_back(m); 00098 return true; 00099 } 00100 00101 SQInstance *SQClass::CreateInstance() 00102 { 00103 if(!_locked) Lock(); 00104 return SQInstance::Create(_opt_ss(this),this); 00105 } 00106 00107 SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) 00108 { 00109 SQObjectPtr oval; 00110 SQInteger idx = _members->Next(false,refpos,outkey,oval); 00111 if(idx != -1) { 00112 if(_ismethod(oval)) { 00113 outval = _methods[_member_idx(oval)].val; 00114 } 00115 else { 00116 SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val; 00117 outval = _realval(o); 00118 } 00119 } 00120 return idx; 00121 } 00122 00123 bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val) 00124 { 00125 SQObjectPtr idx; 00126 if(_members->Get(key,idx)) { 00127 if(_isfield(idx)) 00128 _defaultvalues[_member_idx(idx)].attrs = val; 00129 else 00130 _methods[_member_idx(idx)].attrs = val; 00131 return true; 00132 } 00133 return false; 00134 } 00135 00136 bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval) 00137 { 00138 SQObjectPtr idx; 00139 if(_members->Get(key,idx)) { 00140 outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs); 00141 return true; 00142 } 00143 return false; 00144 } 00145 00146 /////////////////////////////////////////////////////////////////////// 00147 void SQInstance::Init(SQSharedState *ss) 00148 { 00149 _userpointer = NULL; 00150 _hook = NULL; 00151 __ObjAddRef(_class); 00152 _delegate = _class->_members; 00153 INIT_CHAIN(); 00154 ADD_TO_CHAIN(&_sharedstate->_gc_chain, this); 00155 } 00156 00157 SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize) 00158 { 00159 _memsize = memsize; 00160 _class = c; 00161 SQUnsignedInteger nvalues = _class->_defaultvalues.size(); 00162 for(SQUnsignedInteger n = 0; n < nvalues; n++) { 00163 new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val); 00164 } 00165 Init(ss); 00166 } 00167 00168 SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize) 00169 { 00170 _memsize = memsize; 00171 _class = i->_class; 00172 SQUnsignedInteger nvalues = _class->_defaultvalues.size(); 00173 for(SQUnsignedInteger n = 0; n < nvalues; n++) { 00174 new (&_values[n]) SQObjectPtr(i->_values[n]); 00175 } 00176 Init(ss); 00177 } 00178 00179 void SQInstance::Finalize() 00180 { 00181 SQUnsignedInteger nvalues = _class->_defaultvalues.size(); 00182 __ObjRelease(_class); 00183 _NULL_SQOBJECT_VECTOR(_values,nvalues); 00184 //for(SQUnsignedInteger i = 0; i < nvalues; i++) { 00185 // _values[i].Null(); 00186 // } 00187 } 00188 00189 SQInstance::~SQInstance() 00190 { 00191 REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); 00192 if(_class){ Finalize(); } //if _class is null it was already finalized by the GC 00193 } 00194 00195 bool SQInstance::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) 00196 { 00197 if(type(_class->_metamethods[mm]) != OT_NULL) { 00198 res = _class->_metamethods[mm]; 00199 return true; 00200 } 00201 return false; 00202 } 00203 00204 bool SQInstance::InstanceOf(SQClass *trg) 00205 { 00206 SQClass *parent = _class; 00207 while(parent != NULL) { 00208 if(parent == trg) 00209 return true; 00210 parent = parent->_base; 00211 } 00212 return false; 00213 }
Generated on Tue Jul 12 2022 21:35:49 by
