The Squirrel interpreter. See http://www.squirrel-lang.org/
squirrel/sqclass.cpp@0:97a4f8cc534c, 2014-12-16 (annotated)
- Committer:
- jhnwkmn
- Date:
- Tue Dec 16 10:20:34 2014 +0000
- Revision:
- 0:97a4f8cc534c
Initial import of Squirrel.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jhnwkmn | 0:97a4f8cc534c | 1 | /* |
jhnwkmn | 0:97a4f8cc534c | 2 | see copyright notice in squirrel.h |
jhnwkmn | 0:97a4f8cc534c | 3 | */ |
jhnwkmn | 0:97a4f8cc534c | 4 | #include "sqpcheader.h" |
jhnwkmn | 0:97a4f8cc534c | 5 | #include "sqvm.h" |
jhnwkmn | 0:97a4f8cc534c | 6 | #include "sqtable.h" |
jhnwkmn | 0:97a4f8cc534c | 7 | #include "sqclass.h" |
jhnwkmn | 0:97a4f8cc534c | 8 | #include "sqfuncproto.h" |
jhnwkmn | 0:97a4f8cc534c | 9 | #include "sqclosure.h" |
jhnwkmn | 0:97a4f8cc534c | 10 | |
jhnwkmn | 0:97a4f8cc534c | 11 | |
jhnwkmn | 0:97a4f8cc534c | 12 | |
jhnwkmn | 0:97a4f8cc534c | 13 | SQClass::SQClass(SQSharedState *ss,SQClass *base) |
jhnwkmn | 0:97a4f8cc534c | 14 | { |
jhnwkmn | 0:97a4f8cc534c | 15 | _base = base; |
jhnwkmn | 0:97a4f8cc534c | 16 | _typetag = 0; |
jhnwkmn | 0:97a4f8cc534c | 17 | _hook = NULL; |
jhnwkmn | 0:97a4f8cc534c | 18 | _udsize = 0; |
jhnwkmn | 0:97a4f8cc534c | 19 | _locked = false; |
jhnwkmn | 0:97a4f8cc534c | 20 | _constructoridx = -1; |
jhnwkmn | 0:97a4f8cc534c | 21 | if(_base) { |
jhnwkmn | 0:97a4f8cc534c | 22 | _constructoridx = _base->_constructoridx; |
jhnwkmn | 0:97a4f8cc534c | 23 | _udsize = _base->_udsize; |
jhnwkmn | 0:97a4f8cc534c | 24 | _defaultvalues.copy(base->_defaultvalues); |
jhnwkmn | 0:97a4f8cc534c | 25 | _methods.copy(base->_methods); |
jhnwkmn | 0:97a4f8cc534c | 26 | _COPY_VECTOR(_metamethods,base->_metamethods,MT_LAST); |
jhnwkmn | 0:97a4f8cc534c | 27 | __ObjAddRef(_base); |
jhnwkmn | 0:97a4f8cc534c | 28 | } |
jhnwkmn | 0:97a4f8cc534c | 29 | _members = base?base->_members->Clone() : SQTable::Create(ss,0); |
jhnwkmn | 0:97a4f8cc534c | 30 | __ObjAddRef(_members); |
jhnwkmn | 0:97a4f8cc534c | 31 | |
jhnwkmn | 0:97a4f8cc534c | 32 | INIT_CHAIN(); |
jhnwkmn | 0:97a4f8cc534c | 33 | ADD_TO_CHAIN(&_sharedstate->_gc_chain, this); |
jhnwkmn | 0:97a4f8cc534c | 34 | } |
jhnwkmn | 0:97a4f8cc534c | 35 | |
jhnwkmn | 0:97a4f8cc534c | 36 | void SQClass::Finalize() { |
jhnwkmn | 0:97a4f8cc534c | 37 | _attributes.Null(); |
jhnwkmn | 0:97a4f8cc534c | 38 | _NULL_SQOBJECT_VECTOR(_defaultvalues,_defaultvalues.size()); |
jhnwkmn | 0:97a4f8cc534c | 39 | _methods.resize(0); |
jhnwkmn | 0:97a4f8cc534c | 40 | _NULL_SQOBJECT_VECTOR(_metamethods,MT_LAST); |
jhnwkmn | 0:97a4f8cc534c | 41 | __ObjRelease(_members); |
jhnwkmn | 0:97a4f8cc534c | 42 | if(_base) { |
jhnwkmn | 0:97a4f8cc534c | 43 | __ObjRelease(_base); |
jhnwkmn | 0:97a4f8cc534c | 44 | } |
jhnwkmn | 0:97a4f8cc534c | 45 | } |
jhnwkmn | 0:97a4f8cc534c | 46 | |
jhnwkmn | 0:97a4f8cc534c | 47 | SQClass::~SQClass() |
jhnwkmn | 0:97a4f8cc534c | 48 | { |
jhnwkmn | 0:97a4f8cc534c | 49 | REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); |
jhnwkmn | 0:97a4f8cc534c | 50 | Finalize(); |
jhnwkmn | 0:97a4f8cc534c | 51 | } |
jhnwkmn | 0:97a4f8cc534c | 52 | |
jhnwkmn | 0:97a4f8cc534c | 53 | bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic) |
jhnwkmn | 0:97a4f8cc534c | 54 | { |
jhnwkmn | 0:97a4f8cc534c | 55 | SQObjectPtr temp; |
jhnwkmn | 0:97a4f8cc534c | 56 | bool belongs_to_static_table = type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE || bstatic; |
jhnwkmn | 0:97a4f8cc534c | 57 | if(_locked && !belongs_to_static_table) |
jhnwkmn | 0:97a4f8cc534c | 58 | return false; //the class already has an instance so cannot be modified |
jhnwkmn | 0:97a4f8cc534c | 59 | if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value |
jhnwkmn | 0:97a4f8cc534c | 60 | { |
jhnwkmn | 0:97a4f8cc534c | 61 | _defaultvalues[_member_idx(temp)].val = val; |
jhnwkmn | 0:97a4f8cc534c | 62 | return true; |
jhnwkmn | 0:97a4f8cc534c | 63 | } |
jhnwkmn | 0:97a4f8cc534c | 64 | if(belongs_to_static_table) { |
jhnwkmn | 0:97a4f8cc534c | 65 | SQInteger mmidx; |
jhnwkmn | 0:97a4f8cc534c | 66 | if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) && |
jhnwkmn | 0:97a4f8cc534c | 67 | (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) { |
jhnwkmn | 0:97a4f8cc534c | 68 | _metamethods[mmidx] = val; |
jhnwkmn | 0:97a4f8cc534c | 69 | } |
jhnwkmn | 0:97a4f8cc534c | 70 | else { |
jhnwkmn | 0:97a4f8cc534c | 71 | SQObjectPtr theval = val; |
jhnwkmn | 0:97a4f8cc534c | 72 | if(_base && type(val) == OT_CLOSURE) { |
jhnwkmn | 0:97a4f8cc534c | 73 | theval = _closure(val)->Clone(); |
jhnwkmn | 0:97a4f8cc534c | 74 | _closure(theval)->_base = _base; |
jhnwkmn | 0:97a4f8cc534c | 75 | __ObjAddRef(_base); //ref for the closure |
jhnwkmn | 0:97a4f8cc534c | 76 | } |
jhnwkmn | 0:97a4f8cc534c | 77 | if(type(temp) == OT_NULL) { |
jhnwkmn | 0:97a4f8cc534c | 78 | bool isconstructor; |
jhnwkmn | 0:97a4f8cc534c | 79 | SQVM::IsEqual(ss->_constructoridx, key, isconstructor); |
jhnwkmn | 0:97a4f8cc534c | 80 | if(isconstructor) { |
jhnwkmn | 0:97a4f8cc534c | 81 | _constructoridx = (SQInteger)_methods.size(); |
jhnwkmn | 0:97a4f8cc534c | 82 | } |
jhnwkmn | 0:97a4f8cc534c | 83 | SQClassMember m; |
jhnwkmn | 0:97a4f8cc534c | 84 | m.val = theval; |
jhnwkmn | 0:97a4f8cc534c | 85 | _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size()))); |
jhnwkmn | 0:97a4f8cc534c | 86 | _methods.push_back(m); |
jhnwkmn | 0:97a4f8cc534c | 87 | } |
jhnwkmn | 0:97a4f8cc534c | 88 | else { |
jhnwkmn | 0:97a4f8cc534c | 89 | _methods[_member_idx(temp)].val = theval; |
jhnwkmn | 0:97a4f8cc534c | 90 | } |
jhnwkmn | 0:97a4f8cc534c | 91 | } |
jhnwkmn | 0:97a4f8cc534c | 92 | return true; |
jhnwkmn | 0:97a4f8cc534c | 93 | } |
jhnwkmn | 0:97a4f8cc534c | 94 | SQClassMember m; |
jhnwkmn | 0:97a4f8cc534c | 95 | m.val = val; |
jhnwkmn | 0:97a4f8cc534c | 96 | _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size()))); |
jhnwkmn | 0:97a4f8cc534c | 97 | _defaultvalues.push_back(m); |
jhnwkmn | 0:97a4f8cc534c | 98 | return true; |
jhnwkmn | 0:97a4f8cc534c | 99 | } |
jhnwkmn | 0:97a4f8cc534c | 100 | |
jhnwkmn | 0:97a4f8cc534c | 101 | SQInstance *SQClass::CreateInstance() |
jhnwkmn | 0:97a4f8cc534c | 102 | { |
jhnwkmn | 0:97a4f8cc534c | 103 | if(!_locked) Lock(); |
jhnwkmn | 0:97a4f8cc534c | 104 | return SQInstance::Create(_opt_ss(this),this); |
jhnwkmn | 0:97a4f8cc534c | 105 | } |
jhnwkmn | 0:97a4f8cc534c | 106 | |
jhnwkmn | 0:97a4f8cc534c | 107 | SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) |
jhnwkmn | 0:97a4f8cc534c | 108 | { |
jhnwkmn | 0:97a4f8cc534c | 109 | SQObjectPtr oval; |
jhnwkmn | 0:97a4f8cc534c | 110 | SQInteger idx = _members->Next(false,refpos,outkey,oval); |
jhnwkmn | 0:97a4f8cc534c | 111 | if(idx != -1) { |
jhnwkmn | 0:97a4f8cc534c | 112 | if(_ismethod(oval)) { |
jhnwkmn | 0:97a4f8cc534c | 113 | outval = _methods[_member_idx(oval)].val; |
jhnwkmn | 0:97a4f8cc534c | 114 | } |
jhnwkmn | 0:97a4f8cc534c | 115 | else { |
jhnwkmn | 0:97a4f8cc534c | 116 | SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val; |
jhnwkmn | 0:97a4f8cc534c | 117 | outval = _realval(o); |
jhnwkmn | 0:97a4f8cc534c | 118 | } |
jhnwkmn | 0:97a4f8cc534c | 119 | } |
jhnwkmn | 0:97a4f8cc534c | 120 | return idx; |
jhnwkmn | 0:97a4f8cc534c | 121 | } |
jhnwkmn | 0:97a4f8cc534c | 122 | |
jhnwkmn | 0:97a4f8cc534c | 123 | bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val) |
jhnwkmn | 0:97a4f8cc534c | 124 | { |
jhnwkmn | 0:97a4f8cc534c | 125 | SQObjectPtr idx; |
jhnwkmn | 0:97a4f8cc534c | 126 | if(_members->Get(key,idx)) { |
jhnwkmn | 0:97a4f8cc534c | 127 | if(_isfield(idx)) |
jhnwkmn | 0:97a4f8cc534c | 128 | _defaultvalues[_member_idx(idx)].attrs = val; |
jhnwkmn | 0:97a4f8cc534c | 129 | else |
jhnwkmn | 0:97a4f8cc534c | 130 | _methods[_member_idx(idx)].attrs = val; |
jhnwkmn | 0:97a4f8cc534c | 131 | return true; |
jhnwkmn | 0:97a4f8cc534c | 132 | } |
jhnwkmn | 0:97a4f8cc534c | 133 | return false; |
jhnwkmn | 0:97a4f8cc534c | 134 | } |
jhnwkmn | 0:97a4f8cc534c | 135 | |
jhnwkmn | 0:97a4f8cc534c | 136 | bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval) |
jhnwkmn | 0:97a4f8cc534c | 137 | { |
jhnwkmn | 0:97a4f8cc534c | 138 | SQObjectPtr idx; |
jhnwkmn | 0:97a4f8cc534c | 139 | if(_members->Get(key,idx)) { |
jhnwkmn | 0:97a4f8cc534c | 140 | outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs); |
jhnwkmn | 0:97a4f8cc534c | 141 | return true; |
jhnwkmn | 0:97a4f8cc534c | 142 | } |
jhnwkmn | 0:97a4f8cc534c | 143 | return false; |
jhnwkmn | 0:97a4f8cc534c | 144 | } |
jhnwkmn | 0:97a4f8cc534c | 145 | |
jhnwkmn | 0:97a4f8cc534c | 146 | /////////////////////////////////////////////////////////////////////// |
jhnwkmn | 0:97a4f8cc534c | 147 | void SQInstance::Init(SQSharedState *ss) |
jhnwkmn | 0:97a4f8cc534c | 148 | { |
jhnwkmn | 0:97a4f8cc534c | 149 | _userpointer = NULL; |
jhnwkmn | 0:97a4f8cc534c | 150 | _hook = NULL; |
jhnwkmn | 0:97a4f8cc534c | 151 | __ObjAddRef(_class); |
jhnwkmn | 0:97a4f8cc534c | 152 | _delegate = _class->_members; |
jhnwkmn | 0:97a4f8cc534c | 153 | INIT_CHAIN(); |
jhnwkmn | 0:97a4f8cc534c | 154 | ADD_TO_CHAIN(&_sharedstate->_gc_chain, this); |
jhnwkmn | 0:97a4f8cc534c | 155 | } |
jhnwkmn | 0:97a4f8cc534c | 156 | |
jhnwkmn | 0:97a4f8cc534c | 157 | SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize) |
jhnwkmn | 0:97a4f8cc534c | 158 | { |
jhnwkmn | 0:97a4f8cc534c | 159 | _memsize = memsize; |
jhnwkmn | 0:97a4f8cc534c | 160 | _class = c; |
jhnwkmn | 0:97a4f8cc534c | 161 | SQUnsignedInteger nvalues = _class->_defaultvalues.size(); |
jhnwkmn | 0:97a4f8cc534c | 162 | for(SQUnsignedInteger n = 0; n < nvalues; n++) { |
jhnwkmn | 0:97a4f8cc534c | 163 | new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val); |
jhnwkmn | 0:97a4f8cc534c | 164 | } |
jhnwkmn | 0:97a4f8cc534c | 165 | Init(ss); |
jhnwkmn | 0:97a4f8cc534c | 166 | } |
jhnwkmn | 0:97a4f8cc534c | 167 | |
jhnwkmn | 0:97a4f8cc534c | 168 | SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize) |
jhnwkmn | 0:97a4f8cc534c | 169 | { |
jhnwkmn | 0:97a4f8cc534c | 170 | _memsize = memsize; |
jhnwkmn | 0:97a4f8cc534c | 171 | _class = i->_class; |
jhnwkmn | 0:97a4f8cc534c | 172 | SQUnsignedInteger nvalues = _class->_defaultvalues.size(); |
jhnwkmn | 0:97a4f8cc534c | 173 | for(SQUnsignedInteger n = 0; n < nvalues; n++) { |
jhnwkmn | 0:97a4f8cc534c | 174 | new (&_values[n]) SQObjectPtr(i->_values[n]); |
jhnwkmn | 0:97a4f8cc534c | 175 | } |
jhnwkmn | 0:97a4f8cc534c | 176 | Init(ss); |
jhnwkmn | 0:97a4f8cc534c | 177 | } |
jhnwkmn | 0:97a4f8cc534c | 178 | |
jhnwkmn | 0:97a4f8cc534c | 179 | void SQInstance::Finalize() |
jhnwkmn | 0:97a4f8cc534c | 180 | { |
jhnwkmn | 0:97a4f8cc534c | 181 | SQUnsignedInteger nvalues = _class->_defaultvalues.size(); |
jhnwkmn | 0:97a4f8cc534c | 182 | __ObjRelease(_class); |
jhnwkmn | 0:97a4f8cc534c | 183 | _NULL_SQOBJECT_VECTOR(_values,nvalues); |
jhnwkmn | 0:97a4f8cc534c | 184 | //for(SQUnsignedInteger i = 0; i < nvalues; i++) { |
jhnwkmn | 0:97a4f8cc534c | 185 | // _values[i].Null(); |
jhnwkmn | 0:97a4f8cc534c | 186 | // } |
jhnwkmn | 0:97a4f8cc534c | 187 | } |
jhnwkmn | 0:97a4f8cc534c | 188 | |
jhnwkmn | 0:97a4f8cc534c | 189 | SQInstance::~SQInstance() |
jhnwkmn | 0:97a4f8cc534c | 190 | { |
jhnwkmn | 0:97a4f8cc534c | 191 | REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); |
jhnwkmn | 0:97a4f8cc534c | 192 | if(_class){ Finalize(); } //if _class is null it was already finalized by the GC |
jhnwkmn | 0:97a4f8cc534c | 193 | } |
jhnwkmn | 0:97a4f8cc534c | 194 | |
jhnwkmn | 0:97a4f8cc534c | 195 | bool SQInstance::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) |
jhnwkmn | 0:97a4f8cc534c | 196 | { |
jhnwkmn | 0:97a4f8cc534c | 197 | if(type(_class->_metamethods[mm]) != OT_NULL) { |
jhnwkmn | 0:97a4f8cc534c | 198 | res = _class->_metamethods[mm]; |
jhnwkmn | 0:97a4f8cc534c | 199 | return true; |
jhnwkmn | 0:97a4f8cc534c | 200 | } |
jhnwkmn | 0:97a4f8cc534c | 201 | return false; |
jhnwkmn | 0:97a4f8cc534c | 202 | } |
jhnwkmn | 0:97a4f8cc534c | 203 | |
jhnwkmn | 0:97a4f8cc534c | 204 | bool SQInstance::InstanceOf(SQClass *trg) |
jhnwkmn | 0:97a4f8cc534c | 205 | { |
jhnwkmn | 0:97a4f8cc534c | 206 | SQClass *parent = _class; |
jhnwkmn | 0:97a4f8cc534c | 207 | while(parent != NULL) { |
jhnwkmn | 0:97a4f8cc534c | 208 | if(parent == trg) |
jhnwkmn | 0:97a4f8cc534c | 209 | return true; |
jhnwkmn | 0:97a4f8cc534c | 210 | parent = parent->_base; |
jhnwkmn | 0:97a4f8cc534c | 211 | } |
jhnwkmn | 0:97a4f8cc534c | 212 | return false; |
jhnwkmn | 0:97a4f8cc534c | 213 | } |