/**
		15.2.4.5 Object.prototype.hasOwnProperty (V)
		When the hasOwnProperty method is called with argument V, the following steps are taken:
		1. Let O be this object.
		2. Call ToString(V).
		3. If O doesn’t have a property with the name given by Result(2), return false.
		4. Return true.
		NOTE Unlike [[HasProperty]] (section 8.6.2.4), this method does not consider objects in the prototype chain.
     */
	bool ObjectClass::_hasOwnProperty(Atom thisAtom, Stringp name)
	{
		AvmCore* core = this->core();
		name = name ? core->internString(name) : (Stringp)core->knull;

		Traitsp t = NULL;
		switch (atomKind(thisAtom))
		{
			case kObjectType:
			{
				// ISSUE should this look in traits and dynamic vars, or just dynamic vars.
				ScriptObject* obj = AvmCore::atomToScriptObject(thisAtom);
				if (obj->hasStringProperty(name))
					return true;
				t = obj->traits();
				break;
			}
			case kNamespaceType:
			case kStringType:
			case kBooleanType:
			case kDoubleType:
			case kIntegerType:
				t = toplevel()->toTraits(thisAtom);
				break;
			default:
				return false;
		}
		return t->getTraitsBindings()->findBinding(name, core->publicNamespace) != BIND_NONE;
	}
Esempio n. 2
0
File: VTable.cpp Progetto: bsdf/trx
    VTable* VTable::newParameterizedVTable(Traits* param_traits, Stringp fullname)
    {
        Toplevel* toplevel = this->toplevel();
        AvmCore* core = toplevel->core();
        Namespacep traitsNs = this->traits->ns();

        GCRef<builtinClassManifest> builtinClasses = toplevel->builtinClasses();
        GCRef<ObjectVectorClass> vectorobj_cls = builtinClasses->get_Vector_objectClass();
        GCRef<ScopeChain> vectorobj_cscope = vectorobj_cls->vtable->init->scope();
        GCRef<ScopeChain> vectorobj_iscope = vectorobj_cls->ivtable()->init->scope();
        VTable* objVecVTable = vectorobj_cls->vtable;
        AbcEnv* objVecAbcEnv = vectorobj_cscope->abcEnv();
        Toplevel* objVecToplevel = objVecVTable->toplevel();
        VTable* objVecIVTable = objVecVTable->ivtable;

        // these cases should all be filtered out by the caller;
        // we only want to handle Vector<SomeObject> here
        AvmAssert(param_traits != NULL &&
                    param_traits != toplevel->intClass()->vtable->traits->itraits &&
                    param_traits != toplevel->uintClass()->vtable->traits->itraits &&
                    param_traits != toplevel->numberClass()->vtable->traits->itraits);

        PoolObject* traitsPool = this->traits->pool;

        Stringp classname = core->internString(fullname->appendLatin1("$"));
        Traits* ctraits = core->domainMgr()->findTraitsInPoolByNameAndNS(traitsPool, classname, traitsNs);
        Traits* itraits;
        if (!ctraits)
        {
            // important: base the new ctraits on objVecVTable->traits, *not* this->traits;
            // we want the result to be based off ObjectVectorClass, not VectorClass
            // (otherwise sizeofInstance would be too small and we'd be crashy)
            ctraits = objVecVTable->traits->newParameterizedCTraits(classname, traitsNs);
            ctraits->verifyBindings(toplevel);

            itraits = traitsPool->resolveParameterizedType(toplevel, this->ivtable->traits, param_traits);
            ctraits->itraits = itraits;
        }
        else
        {
            itraits = ctraits->itraits;
        }

        AvmAssert(itraits != NULL);

        VTable* class_ivtable = builtinClasses->get_ClassClass()->ivtable();

        VTable* cvtab = core->newVTable(ctraits, class_ivtable, objVecToplevel);
        ScopeChain* cvtab_cscope = vectorobj_cscope->cloneWithNewVTable(core->GetGC(), cvtab, objVecAbcEnv);

        VTable* ivtab = core->newVTable(itraits, objVecIVTable, objVecToplevel);
        ScopeChain* ivtab_iscope = vectorobj_iscope->cloneWithNewVTable(core->GetGC(), ivtab, objVecAbcEnv);
        cvtab->ivtable = ivtab;
        ivtab->init = objVecIVTable->init;

        cvtab->resolveSignatures(cvtab_cscope);
        ivtab->resolveSignatures(ivtab_iscope);

        return cvtab;
    }
Esempio n. 3
0
    /**
        15.2.4.5 Object.prototype.hasOwnProperty (V)
        When the hasOwnProperty method is called with argument V, the following steps are taken:
        1. Let O be this object.
        2. Call ToString(V).
        3. If O doesn't have a property with the name given by Result(2), return false.
        4. Return true.
        NOTE Unlike [[HasProperty]] (section 8.6.2.4), this method does not consider objects in the prototype chain.
     */
    bool ObjectClass::_hasOwnProperty(Atom thisAtom, Stringp name)
    {
        AvmCore* core = this->core();
        name = name ? core->internString(name) : (Stringp)core->knull;

        Traitsp t = NULL;
        switch (atomKind(thisAtom))
        {
            case kObjectType:
            {
                // ISSUE should this look in traits and dynamic vars, or just dynamic vars.
                ScriptObject* obj = AvmCore::atomToScriptObject(thisAtom);
                // TODO
                // The change below is important as otherwise we will throw error in a call to hasAtomProperty for ByteArrayObject.
                // This gets us back to the behaviour which we had in Marlin.
                // A bugzilla bug [ 562224 ] has been created to address this issue more cleanly in near future
                return obj->traits()->getTraitsBindings()->findBinding(name, core->findPublicNamespace()) != BIND_NONE ||
                    obj->hasStringProperty(name);
            }
            case kNamespaceType:
            case kStringType:
            case kBooleanType:
            case kDoubleType:
            case kIntptrType:
                t = toplevel()->toTraits(thisAtom);
                break;
            default:
                return false;
        }
        // NOTE use caller's public namespace
        return t->getTraitsBindings()->findBinding(name, core->findPublicNamespace()) != BIND_NONE;
    }
Esempio n. 4
0
	ClassClosure* DomainObject::getClass(Stringp name)
	{
		AvmCore *core = this->core();

		if (name == NULL) {
			toplevel()->throwArgumentError(kNullArgumentError, core->toErrorString("name"));
		}

			
		// Search for a dot from the end.
        int dot = name->lastIndexOf(core->cachedChars[(int)'.']);
		
		// If there is a '.', this is a fully-qualified
		// class name in a package.  Must turn it into
		// a namespace-qualified multiname.
		Namespace* ns;
		Stringp className;
		if (dot >= 0) {
            Stringp uri = core->internString(name->substring(0, dot));
			ns = core->internNamespace(core->newNamespace(uri));
            className = core->internString(name->substring(dot+1, name->length()));
		} else {
			ns = core->publicNamespace;
			className = core->internString(name);
		}

		Multiname multiname(ns, className);

        // OOO: In the distribution, we search core->codeContext()->domainEnv rather than
        // our own domainEnv, which is surely a bug?
        ScriptObject *container = finddef(multiname, domainEnv);
		if (!container) {
			toplevel()->throwTypeError(kClassNotFoundError, core->toErrorString(&multiname));
		}
		Atom atom = toplevel()->getproperty(container->atom(),
											&multiname,
											container->vtable);

		if (!AvmCore::istype(atom, core->traits.class_itraits)) {
			toplevel()->throwTypeError(kClassNotFoundError, core->toErrorString(&multiname));
		}
		return (ClassClosure*)AvmCore::atomToScriptObject(atom);
	}
	void ObjectClass::_setPropertyIsEnumerable(Atom thisAtom, Stringp name, bool enumerable)
	{
		AvmCore* core = this->core();
		name = name ? core->internString(name) : (Stringp)core->knull;

		if ((thisAtom&7) == kObjectType)
		{
			ScriptObject* obj = AvmCore::atomToScriptObject(thisAtom);
			obj->setStringPropertyIsEnumerable(name, enumerable);
		}
		else
		{
			// cannot create properties on a sealed object.
			Multiname multiname(core->publicNamespace, name);
			toplevel()->throwReferenceError(kWriteSealedError, &multiname, traits());
		}
	}		
Esempio n. 6
0
    void ObjectClass::_setPropertyIsEnumerable(Atom thisAtom, Stringp name, bool enumerable)
    {
        AvmCore* core = this->core();
        name = name ? core->internString(name) : (Stringp)core->knull;

        if (atomKind(thisAtom) == kObjectType)
        {
            ScriptObject* obj = AvmCore::atomToScriptObject(thisAtom);
            obj->setStringPropertyIsEnumerable(name, enumerable);
        }
        else
        {
            // cannot create properties on a sealed object.
            // NOTE just use the unmarked version
            Multiname multiname(core->getAnyPublicNamespace(), name);
            // NOTE use default public
            toplevel()->throwReferenceError(kWriteSealedError, &multiname, traits());
        }
    }
	bool ObjectClass::_propertyIsEnumerable(Atom thisAtom, Stringp name)
	{
		AvmCore* core = this->core();
		name = name ? core->internString(name) : (Stringp)core->knull;

		if ((thisAtom&7) == kObjectType)
		{
			ScriptObject* obj = AvmCore::atomToScriptObject(thisAtom);
			return obj->getStringPropertyIsEnumerable(name);
		}
		else if ((thisAtom&7) == kNamespaceType)
		{
			// Special case:
			// E4X 13.2.5.1, 13.2.5.2 specifies that prefix and uri
			// are not DontEnum.
			return name == core->kuri || name == core->kprefix;
		}
		else
		{
			return false;
		}
	}
    ArrayObject* RegExpObject::_exec(Stringp subject, 
									UTF8String *utf8Subject,
									int startIndex,
									int& matchIndex,
									int& matchLen)
	{
		AvmAssert(subject != NULL);
		AvmAssert(utf8Subject != NULL);
		
		int ovector[OVECTOR_SIZE];
		int results;
		int subjectLength = utf8Subject->length();

		if( startIndex < 0 ||
			startIndex > subjectLength ||
			(results = pcre_exec((pcre*)m_pcreInst,
								NULL,
								utf8Subject->c_str(),
								subjectLength,
								startIndex,
								PCRE_NO_UTF8_CHECK,
								ovector,
								OVECTOR_SIZE)) < 0)
		{
			matchIndex = 0;
			matchLen = 0;
			return NULL;
		}

		AvmCore *core = this->core();
		ArrayObject *a = toplevel()->arrayClass->newArray(results);

		a->setAtomProperty(toplevel()->regexpClass()->kindex,
			   core->intToAtom(Utf8ToUtf16Index(subject, utf8Subject, ovector[0])));
		a->setAtomProperty(toplevel()->regexpClass()->kinput,
			   subject->atom());
		a->setLength(results);

		// set array slots
		for (int i=0; i<results; i++) {
			if (ovector[i*2] > -1) {
				int length = ovector[i*2 + 1] - ovector[i*2];
				Atom match = stringFromUTF8(utf8Subject->c_str()+ovector[i*2], length);
				a->setUintProperty(i, match);
			} else {
				a->setUintProperty(i, undefinedAtom);
			}
		}

		// handle named groups
		if (m_hasNamedGroups)
		{
			int entrySize;
			pcre_fullinfo((pcre*)m_pcreInst, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrySize);
	 
			int nameCount;
			pcre_fullinfo((pcre*)m_pcreInst, NULL, PCRE_INFO_NAMECOUNT, &nameCount);
	 
			// this space is freed when (pcre*)m_pcreInst is freed 
			char *nameTable;
			pcre_fullinfo((pcre*)m_pcreInst, NULL, PCRE_INFO_NAMETABLE, &nameTable);
	 
			/* nameTable is a series of fixed length entries (entrySize) 
			   the first two bytes are the index into the ovector and the result
			   is a null terminated string (the subgroup name) */
			for (int i = 0; i < nameCount; i++)
			{
				int nameIndex, length;
				nameIndex = (nameTable[0] << 8) + nameTable[1];
				length = ovector[nameIndex * 2 + 1] - ovector[ nameIndex * 2 ];

				Atom name = stringFromUTF8((char*)(nameTable+2), (uint32)strlen(nameTable+2));
				name = core->internString(name)->atom();

				Atom value = stringFromUTF8(utf8Subject->c_str()+ovector[nameIndex*2], length);

				a->setAtomProperty(name, value);

				nameTable += entrySize;
			}
		}
		
		matchIndex = ovector[0];
		matchLen = ovector[1]-ovector[0];

		return a;
	}