sqclass.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /* see copyright notice in squirrel.h */
  2. #ifndef _SQCLASS_H_
  3. #define _SQCLASS_H_
  4. struct SQInstance;
  5. struct SQClassMember {
  6. SQObjectPtr val;
  7. SQObjectPtr attrs;
  8. void Null() {
  9. val.Null();
  10. attrs.Null();
  11. }
  12. };
  13. typedef sqvector<SQClassMember> SQClassMemberVec;
  14. #define MEMBER_TYPE_METHOD 0x01000000
  15. #define MEMBER_TYPE_FIELD 0x02000000
  16. #define MEMBER_MAX_COUNT 0x00FFFFFF
  17. #define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD)
  18. #define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD)
  19. #define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD|i))
  20. #define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD|i))
  21. #define _member_type(o) (_integer(o)&0xFF000000)
  22. #define _member_idx(o) (_integer(o)&0x00FFFFFF)
  23. struct SQClass : public CHAINABLE_OBJ
  24. {
  25. SQClass(SQSharedState *ss,SQClass *base);
  26. public:
  27. static SQClass* Create(SQSharedState *ss,SQClass *base) {
  28. SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass));
  29. new (newclass) SQClass(ss, base);
  30. return newclass;
  31. }
  32. ~SQClass();
  33. bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic);
  34. bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
  35. if(_members->Get(key,val)) {
  36. if(_isfield(val)) {
  37. SQObjectPtr &o = _defaultvalues[_member_idx(val)].val;
  38. val = _realval(o);
  39. }
  40. else {
  41. val = _methods[_member_idx(val)].val;
  42. }
  43. return true;
  44. }
  45. return false;
  46. }
  47. bool Exists(const SQObjectPtr &key) {
  48. return _members->Exists(key);
  49. }
  50. bool Set(const SQObjectPtr &key,const SQObjectPtr &val) {
  51. SQObjectPtr idx;
  52. if(_members->Get(key,idx) && !_isfield(idx)) {
  53. //if(_isfield(idx)) _members->Set(key, val);
  54. //else
  55. return Set(idx, val);
  56. }
  57. return false;
  58. }
  59. bool Set(SQObjectPtr &idx, const SQObjectPtr &val){
  60. SQClassMember &m = _methods[_member_idx(idx)];
  61. if(!(sq_type(m.val) == OT_CLOSURE || sq_type(m.val) == OT_NATIVECLOSURE)){
  62. m.val = val;
  63. return true;
  64. }
  65. return false;
  66. }
  67. bool GetConstructor(SQObjectPtr &ctor)
  68. {
  69. if(_constructoridx != -1) {
  70. ctor = _methods[_constructoridx].val;
  71. return true;
  72. }
  73. return false;
  74. }
  75. bool GetDestructor(SQObjectPtr &dtor)
  76. {
  77. if(_destructoridx != -1) {
  78. dtor = _methods[_destructoridx].val;
  79. return true;
  80. }
  81. return false;
  82. }
  83. bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val);
  84. bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval);
  85. void Lock() { _locked = true; if(_base) _base->Lock(); }
  86. void Release() {
  87. if (_hook) { _hook(_typetag,0, 0);}
  88. sq_delete(this, SQClass);
  89. }
  90. void Finalize();
  91. #ifndef NO_GARBAGE_COLLECTOR
  92. void Mark(SQCollectable ** );
  93. SQObjectType GetType() {return OT_CLASS;}
  94. #endif
  95. SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
  96. SQInstance *CreateInstance();
  97. SQTable *_members;
  98. SQClass *_base;
  99. SQClassMemberVec _defaultvalues;
  100. SQClassMemberVec _methods;
  101. SQObjectPtr _metamethods[MT_LAST];
  102. SQObjectPtr _attributes;
  103. SQUserPointer _typetag;
  104. SQRELEASEHOOK _hook;
  105. SQInteger _udsize;
  106. SQInt16 _constructoridx;
  107. SQInt16 _destructoridx;
  108. bool _locked;
  109. };
  110. #define calcinstancesize(_theclass_) \
  111. (_theclass_->_udsize + sq_aligning(sizeof(SQInstance) + (sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0))))
  112. struct SQInstance : public SQDelegable
  113. {
  114. private:
  115. void Init(SQSharedState *ss);
  116. SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize);
  117. SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize);
  118. public:
  119. static SQInstance* Create(SQSharedState *ss, SQClass *theclass) {
  120. SQInteger size = calcinstancesize(theclass);
  121. SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
  122. new (newinst) SQInstance(ss, theclass, size);
  123. if(theclass->_udsize) {
  124. newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize);
  125. }
  126. return newinst;
  127. }
  128. SQInstance *Clone(SQSharedState *ss)
  129. {
  130. SQInteger size = calcinstancesize(_class);
  131. SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
  132. new (newinst) SQInstance(ss, this,size);
  133. if(_class->_udsize) {
  134. newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize);
  135. }
  136. return newinst;
  137. }
  138. ~SQInstance();
  139. bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
  140. if(_class->_members->Get(key,val)) {
  141. if(_isfield(val)) {
  142. SQObjectPtr &o = _values[_member_idx(val)];
  143. val = _realval(o);
  144. }
  145. else {
  146. val = _class->_methods[_member_idx(val)].val;
  147. }
  148. return true;
  149. }
  150. return false;
  151. }
  152. bool Exists(const SQObjectPtr &key) {
  153. return _class->_members->Exists(key);
  154. }
  155. bool Set(const SQObjectPtr &key,const SQObjectPtr &val) {
  156. SQObjectPtr idx;
  157. if(_class->_members->Get(key,idx)){
  158. if(_isfield(idx)) {
  159. _values[_member_idx(idx)] = val;
  160. return true;
  161. }
  162. else
  163. {
  164. return _class->Set(idx, val);
  165. }
  166. }
  167. return false;
  168. }
  169. void Release() {
  170. _uiRef++;
  171. if (_hook) {
  172. #if !defined(NO_GARBAGE_COLLECTOR) && defined(SQ_WITH_DELAYED_RELEASE_HOOKS)
  173. _sharedstate->AddDelayedReleaseHook(_hook, _userpointer, 0);
  174. #else
  175. _hook(_userpointer,0, 0);
  176. #endif
  177. }
  178. _uiRef--;
  179. if(_uiRef > 0) return;
  180. SQInteger size = _memsize;
  181. this->~SQInstance();
  182. SQ_FREE(this, size);
  183. }
  184. void Finalize();
  185. #ifndef NO_GARBAGE_COLLECTOR
  186. void Mark(SQCollectable ** );
  187. SQObjectType GetType() {return OT_INSTANCE;}
  188. #endif
  189. bool InstanceOf(SQClass *trg);
  190. bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
  191. SQClass *_class;
  192. SQUserPointer _userpointer;
  193. SQRELEASEHOOK _hook;
  194. SQInteger _memsize;
  195. SQObjectPtr _values[1];
  196. };
  197. #endif //_SQCLASS_H_