// 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;
}
Example #2
0
    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;
	}
Example #5
0
	void weakRefSweepLarge()
	{
		GCWeakRef *ref = createWeakRef(5000);
		collect();
		gc->CleanStack(true);
		collect();
		(void)ref;
		GCAssert(ref->get() == NULL);
	}
Example #6
0
	void weakRefFreeLarge()
	{
		GCWeakRef *ref = createWeakRef(5000);
		delete ref->get();
		GCAssert(ref->get() == NULL);
	}
Example #7
0
	void weakRefFreeSmall()
	{
		GCWeakRef *ref = createWeakRef();
		delete ref->get();
		GCAssert(ref->get() == NULL);
	}