sqclass.h 4.9 KB

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