The Squirrel interpreter. See http://www.squirrel-lang.org/

Dependents:   Squirrel

Committer:
jhnwkmn
Date:
Tue Dec 16 10:20:34 2014 +0000
Revision:
0:97a4f8cc534c
Initial import of Squirrel.

Who changed what in which revision?

UserRevisionLine numberNew 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 }