public virtual void SelfClear() { mName = null; mHash = 0; mFlags = 0; mValue = new Variant(); mNext = null; mSymFlags = SYMBOL_INIT; }
public CustomObject(int hashbits) : base() { // デバッグ系はなし // if(TJSObjectHashMapEnabled()) TJSAddObjectHashRecord(this); mRebuildHashMagic = mGlobalRebuildHashMagic; if (hashbits > OBJECT_HASH__BITS_LIMITS) { hashbits = OBJECT_HASH__BITS_LIMITS; } mHashSize = (1 << hashbits); mHashMask = mHashSize - 1; mSymbols = new SymbolData[mHashSize]; for (int i = 0; i < mHashSize; i++) { mSymbols[i] = new SymbolData(); } //mIsInvalidated = false; //mIsInvalidating = false; mCallFinalize = true; //mCallMissing = false; //mProsessingMissing = false; if (mFinalizeName == null) { // first time; initialize 'finalize' name and 'missing' name mFinalizeName = TJS.MapGlobalStringMap("finalize"); mMissingName = TJS.MapGlobalStringMap("missing"); } mfinalize_name = mFinalizeName; mmissing_name = mMissingName; mClassInstances = new NativeInstance[MAX_NATIVE_CLASS]; mClassIDs = new int[MAX_NATIVE_CLASS]; for (int i_1 = 0; i_1 < MAX_NATIVE_CLASS; i_1++) { mClassIDs[i_1] = -1; } mClassNames = new AList<string>(); //mPrimaryClassInstances; mPrimaryClassID = -1; }
/// <exception cref="Kirikiri.Tjs2.TJSException"></exception> private void RebuildHash() { // rebuild hash table mRebuildHashMagic = mGlobalRebuildHashMagic; // decide new hash table size int r; int v = mCount; if ((v & unchecked((int)(0xffff0000))) != 0) { r = 16; v >>= 16; } else { r = 0; } if ((v & unchecked((int)(0xff00))) != 0) { r += 8; v >>= 8; } if ((v & unchecked((int)(0xf0))) != 0) { r += 4; v >>= 4; } v <<= 1; int newhashbits = r + ((unchecked((int)(0xffffaa50)) >> v) & unchecked((int)(0x03 ))) + 2; if (newhashbits > OBJECT_HASH__BITS_LIMITS) { newhashbits = OBJECT_HASH__BITS_LIMITS; } int newhashsize = (1 << newhashbits); if (newhashsize == mHashSize) { return; } int newhashmask = newhashsize - 1; int orgcount = mCount; // allocate new hash space SymbolData[] newsymbols = new SymbolData[newhashsize]; for (int i = 0; i < newhashsize; i++) { newsymbols[i] = new SymbolData(); } // enumerate current symbol and push to new hash space try { //memset(newsymbols, 0, sizeof(tTJSSymbolData) * newhashsize); //int i; //SymbolData lv1 = mSymbols[0]; //SymbolData lv1lim = mSymbols[mHashSize]; // 末尾か、iterator のように处理してるんだな for (int i_1 = 0; i_1 < mHashSize; i_1++) { //for( ; lv1 < lv1lim; lv1++ ) { SymbolData lv1 = mSymbols[i_1]; SymbolData d = lv1.mNext; while (d != null) { SymbolData nextd = d.mNext; if ((d.mSymFlags & SYMBOL_USING) != 0) { // d->ReShare(); SymbolData data = AddTo(d.mName, newsymbols, newhashmask); if (data != null) { //data.mValue = d.mValue; data.mValue.CopyRef(d.mValue); //GetValue(data).CopyRef(*(tTJSVariant*)(&(d->Value))); data.mSymFlags &= ~(SYMBOL_HIDDEN | SYMBOL_STATIC); data.mSymFlags |= d.mSymFlags & (SYMBOL_HIDDEN | SYMBOL_STATIC); } } //checkObjectClosureAdd( (Variant)data.mValue ); d = nextd; } if ((lv1.mSymFlags & SYMBOL_USING) != 0) { // lv1->ReShare(); SymbolData data = AddTo(lv1.mName, newsymbols, newhashmask); if (data != null) { //data.mValue = lv1.mValue; data.mValue.CopyRef(lv1.mValue); //GetValue(data).CopyRef(*(tTJSVariant*)(&(lv1->Value))); data.mSymFlags &= ~(SYMBOL_HIDDEN | SYMBOL_STATIC); data.mSymFlags |= lv1.mSymFlags & (SYMBOL_HIDDEN | SYMBOL_STATIC); } } } } catch (TJSException e) { //checkObjectClosureAdd( (Variant)data.mValue ); // recover int _HashMask = mHashMask; int _HashSize = mHashSize; SymbolData[] _Symbols = mSymbols; mSymbols = newsymbols; mHashSize = newhashsize; mHashMask = newhashmask; DeleteAllMembers(); mSymbols = null; mHashMask = _HashMask; mHashSize = _HashSize; mSymbols = _Symbols; mCount = orgcount; throw; } // delete all current members DeleteAllMembers(); mSymbols = null; // assign new members mSymbols = newsymbols; mHashSize = newhashsize; mHashMask = newhashmask; mCount = orgcount; }
/// <exception cref="Kirikiri.Tjs2.TJSException"></exception> private SymbolData AddTo(string name, SymbolData[] newdata, int newhashmask) { // similar to Add, except for adding member to new hash space. if (name == null) { return null; } // at this point, the member must not exist in destination hash space int hash; hash = name.GetHashCode(); SymbolData lv1 = newdata[hash & newhashmask]; SymbolData data; if ((lv1.mSymFlags & SYMBOL_USING) != 0) { // lv1 is using // make a chain and insert it after lv1 data = new SymbolData(); data.SelfClear(); data.mNext = lv1.mNext; lv1.mNext = data; data.SetName(name, hash); data.mSymFlags |= SYMBOL_USING; } else { // lv1 is unused if ((lv1.mSymFlags & SYMBOL_INIT) == 0) { lv1.SelfClear(); } lv1.SetName(name, hash); lv1.mSymFlags |= SYMBOL_USING; data = lv1; } // count is not incremented return data; }
// Adds the symbol, returns the newly created data; // if already exists, returns the data. /// <exception cref="Kirikiri.Tjs2.TJSException"></exception> private SymbolData Add(string name) { // add a data element named "name". // return existing element if the element named "name" is already alive. if (name == null) { return null; } SymbolData data; data = Find(name); if (data != null) { // the element is already alive return data; } int hash = name.GetHashCode(); int pos = (hash & mHashMask); //if( LOGD ) Logger.log("Symbol Pos:"+pos); SymbolData lv1 = mSymbols[pos]; if ((lv1.mSymFlags & SYMBOL_USING) != 0) { // lv1 is using // make a chain and insert it after lv1 data = new SymbolData(); data.SelfClear(); data.mNext = lv1.mNext; lv1.mNext = data; data.SetName(name, hash); data.mSymFlags |= SYMBOL_USING; } else { // lv1 is unused if ((lv1.mSymFlags & SYMBOL_INIT) == 0) { lv1.SelfClear(); } lv1.SetName(name, hash); lv1.mSymFlags |= SYMBOL_USING; data = lv1; } mCount++; return data; }
/// <exception cref="Kirikiri.Tjs2.TJSException"></exception> private static bool EnumCallback(int flags, EnumMembersCallback callback, Variant value, Dispatch2 objthis, SymbolData data) { int newflags = 0; if ((data.mSymFlags & SYMBOL_HIDDEN) != 0) { newflags |= Interface.HIDDENMEMBER; } if ((data.mSymFlags & SYMBOL_STATIC) != 0) { newflags |= Interface.STATICMEMBER; } value.Clear(); if ((flags & Interface.ENUM_NO_VALUE) == 0) { bool getvalues = false; if ((flags & Interface.IGNOREPROP) == 0) { Variant targ = data.mValue; if (targ.IsObject()) { VariantClosure tvclosure = targ.AsObjectClosure(); int hr = Error.E_NOTIMPL; if (tvclosure.mObject != null) { Dispatch2 disp = tvclosure.mObjThis != null ? tvclosure.mObjThis : objthis; hr = tvclosure.mObject.PropGet(0, null, value, disp); } if (hr >= 0) { getvalues = true; } else { if (hr != Error.E_NOTIMPL && hr != Error.E_INVALIDTYPE && hr != Error.E_INVALIDOBJECT) { return false; } } } } if (getvalues == false) { value.CopyRef(data.mValue); } } return callback.Callback(data.mName, newflags, value); }