One script object can have multiple, completely separate DukValues "pointing" to it - in this case, there will be multiple entries in the "ref array" that point to the same object. This will happen if the same script object is put on the stack and turned into a DukValue multiple times independently (copy-constructing/operator=-ing DukValues will not do this!). This is okay, as we are only keeping
| 27 | // would probably be amortized constant-time lookup), but I am guessing constructing many separate DukValues that point |
| 28 | // to the same script object isn't a very common thing. |
| 29 | class DukValue { |
| 30 | public: |
| 31 | enum Type : uint8_t { |
| 32 | //NONE = DUK_TYPE_NONE, |
| 33 | UNDEFINED = DUK_TYPE_UNDEFINED, |
| 34 | NULLREF = DUK_TYPE_NULL, |
| 35 | BOOLEAN = DUK_TYPE_BOOLEAN, |
| 36 | NUMBER = DUK_TYPE_NUMBER, |
| 37 | STRING = DUK_TYPE_STRING, |
| 38 | OBJECT = DUK_TYPE_OBJECT, |
| 39 | BUFFER = DUK_TYPE_BUFFER, // not implemented |
| 40 | POINTER = DUK_TYPE_POINTER, |
| 41 | LIGHTFUNC = DUK_TYPE_LIGHTFUNC // not implemented |
| 42 | }; |
| 43 | |
| 44 | // default constructor just makes an undefined-type DukValue |
| 45 | inline DukValue() : mContext(NULL), mType(UNDEFINED), mRefCount(NULL) {} |
| 46 | |
| 47 | virtual ~DukValue() { |
| 48 | // release any references we have |
| 49 | release_ref_count(); |
| 50 | } |
| 51 | |
| 52 | // move constructor |
| 53 | inline DukValue(DukValue&& move) { |
| 54 | mContext = move.mContext; |
| 55 | mType = move.mType; |
| 56 | mPOD = move.mPOD; |
| 57 | mRefCount = move.mRefCount; |
| 58 | |
| 59 | if (mType == STRING) |
| 60 | mString = std::move(move.mString); |
| 61 | |
| 62 | move.mType = UNDEFINED; |
| 63 | move.mRefCount = NULL; |
| 64 | } |
| 65 | |
| 66 | inline DukValue& operator=(const DukValue& rhs) { |
| 67 | // free whatever we had |
| 68 | release_ref_count(); |
| 69 | |
| 70 | // copy things |
| 71 | mContext = rhs.mContext; |
| 72 | mType = rhs.mType; |
| 73 | mPOD = rhs.mPOD; |
| 74 | |
| 75 | if (mType == STRING) |
| 76 | mString = rhs.mString; |
| 77 | |
| 78 | if (mType == OBJECT) |
| 79 | { |
| 80 | // ref counting increment |
| 81 | if (rhs.mRefCount == NULL) { |
| 82 | // not ref counted before, need to allocate memory |
| 83 | const_cast<DukValue&>(rhs).mRefCount = new int(2); |
| 84 | mRefCount = rhs.mRefCount; |
| 85 | } else { |
| 86 | // already refcounting, just increment |
nothing calls this directly
no test coverage detected