sqclass.h 5.4 KB

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