// Function called as constructor ... not supported from user code // this = argv[0] (ignored) // arg1 = argv[1] // argN = argv[argc] MethodClosure* MethodClosureClass::create(MethodEnv* m, Atom obj) { WeakKeyHashtable* mcTable = m->getMethodClosureTable(); Atom mcWeakAtom = mcTable->get(obj); GCWeakRef* ref = (GCWeakRef*)AvmCore::atomToGCObject(mcWeakAtom); MethodClosure* mc; if (!ref || !ref->get()) { VTable* ivtable = this->ivtable(); mc = (new (core()->GetGC(), ivtable->getExtraSize()) MethodClosure(ivtable, m, obj)); // since MC inherits from CC, we must explicitly set the prototype and delegate since the // ctor will leave those null (and without delegate set, apply() and friends won't be found // in pure ES3 code) mc->prototype = prototype; mc->setDelegate(prototype); mcWeakAtom = AvmCore::gcObjectToAtom(mc->GetWeakRef()); mcTable->add(obj, mcWeakAtom); } else { mc = (MethodClosure*)ref->get(); } return mc; }
Atom DictionaryObject::nextName(int index) { AvmAssert(index > 0); HeapHashtable* hht = getHeapHashtable(); Atom m = hht->keyAt(index); Atom k = AvmCore::isNullOrUndefined(m) ? nullStringAtom : m; if (AvmCore::isGenericObject(k) && hht->weakKeys()) { GCWeakRef* ref = (GCWeakRef*)AvmCore::atomToGenericObject(k); union { GCObject* key_o; ScriptObject* key; }; key_o = ref->get(); if (key) { AvmAssert(key->traits() != NULL); return key->atom(); } return undefinedAtom; } return k; }
int DictionaryObject::nextNameIndex(int index) { AvmAssert(index >= 0); if (index != 0) { index = index<<1; } Hashtable *ht = getTable(); // this can happen if you break in debugger in a subclasses constructor before super // has been called #ifdef DEBUGGER if(!ht) { return 0; } #endif // DEBUGGER // Advance to first non-empty slot. int numAtoms = ht->getNumAtoms(); while (index < numAtoms) { Atom a = ht->getAtoms()[index]; if(weakKeys && AvmCore::isGCObject(a)) { GCWeakRef *weakRef = (GCWeakRef*)AvmCore::atomToGCObject(a); if(weakRef->get()) return (index>>1)+1; else { ht->getAtoms()[index] = Hashtable::DELETED; ht->getAtoms()[index+1] = Hashtable::DELETED; ht->setHasDeletedItems(true); } } else if(a != 0 && a != Hashtable::DELETED) {
Atom DictionaryObject::nextName(int index) { Atom k = ScriptObject::nextName(index); if(weakKeys && AvmCore::isGCObject(k)) { GCWeakRef *ref = (GCWeakRef*) (k&~7); if(ref->get()) { ScriptObject *key = ((ScriptObject*)ref->get()); AvmAssert(key->traits() != NULL); return key->atom(); } else return undefinedAtom; } return k; }
void weakRefSweepLarge() { GCWeakRef *ref = createWeakRef(5000); collect(); gc->CleanStack(true); collect(); (void)ref; GCAssert(ref->get() == NULL); }
void weakRefFreeLarge() { GCWeakRef *ref = createWeakRef(5000); delete ref->get(); GCAssert(ref->get() == NULL); }
void weakRefFreeSmall() { GCWeakRef *ref = createWeakRef(); delete ref->get(); GCAssert(ref->get() == NULL); }