Traits* PoolObject::resolveParameterizedType(const Toplevel* toplevel, Traits* base, Traits* param_traits ) const
	{
		Traits* r = NULL;
		if( base == core->traits.vector_itraits)
		{
			// Only vector is parameterizable for now...
			if(!param_traits) // Vector.<*>
				r = core->traits.vectorobj_itraits;  
			else if( param_traits == core->traits.int_itraits)
				r = core->traits.vectorint_itraits;
			else if (param_traits == core->traits.uint_itraits)
				r = core->traits.vectoruint_itraits;
			else if (param_traits == core->traits.number_itraits)
				r = core->traits.vectordouble_itraits;
			else
			{
				Stringp fullname = core->internString( core->concatStrings(core->newString("Vector.<"), 
					core->concatStrings(param_traits->formatClassName(), core->newString(">")))->atom());

				Multiname newname;
				newname.setName(fullname);
				newname.setNamespace(base->ns);

				r = getTraits(newname, toplevel);

				if( !r )
				{
					r = core->traits.vectorobj_itraits->newParameterizedITraits(fullname, base->ns);
					core->traits.vector_itraits->pool->domain->addNamedTrait(fullname, base->ns, r);
				}
			}
		}
		return r;
	}
示例#2
0
MethodEnv* ProxyObject::getMethod(Stringp name)const
{
	//Atom atom=this->getAtomProperty(name->atom());
	//if(AvmCore::isNullOrUndefined(atom)) return NULL;
	//return AvmCore::atomToScriptObject(atom);
	Multiname m;
	m.setName(name);	
	m.setNamespace(m_pNamespace);
	Binding b = avmplus::getBinding(toplevel(), vtable, &m);
	if(AvmCore::bindingKind(b)!=BKIND_METHOD) return NULL;
	return vtable->methods[AvmCore::bindingToMethodId(b)];
}
	PrecomputedMultinames::PrecomputedMultinames(MMgc::GC* gc, PoolObject* pool)
		: MMgc::GCRoot(gc)
		, nNames (0)
	{
		nNames = pool->constantMnCount;
		for ( uint32 i=1 ; i < nNames ; i++ ) {
			Multiname mn;
			pool->parseMultiname(mn, i);
			mn.IncrementRef();
			multinames[i] = mn;
		}
	}
示例#4
0
    // This is always safe.  We must /not/ use WBRC_NULL here, only the full WBRC functions that
    // take the gc and container explicitly will be safe.  See bugzilla 525875.
    void HeapMultiname::setMultiname(MMgc::GC* gc, const void* container, const Multiname& that)
    {
        WBRC(gc, container, &name.name, that.name);

        bool const this_nsset = name.isNsset() != 0;
        bool const that_nsset = that.isNsset() != 0;

        if (this_nsset != that_nsset)
        {
            // gc->rc or vice versa... we have to explicitly null out
            // any existing value (before setting a new one) because WB/WBRC
            // assume any existing value is a GCObject/RCObject respectively.
            if (this_nsset)
                WB_NULL(&name.ns);                      // WB_NULL is safe
            else
                WBRC(gc, container, &name.ns, NULL);    // DO NOT USE WBRC_NULL
        }

        if (that_nsset)
        {
            WB(gc, container, &name.nsset, that.nsset);
        }
        else
        {
            WBRC(gc, container, &name.ns, that.ns);
        }

        name.flags = that.flags;
        name.next_index = that.next_index;
    }
	Traits* PoolObject::resolveTypeName(uint32 index, const Toplevel* toplevel, bool allowVoid/*=false*/) const
	{
		// only save the type name for now.  verifier will resolve to traits
		if (index == 0)
		{
			return NULL;
		}

		// check contents is a multiname.  in the cpool, and type system, kObjectType means multiname.
		if (index >= constantMnCount)
		{
			if (toplevel)
				toplevel->throwVerifyError(kCpoolIndexRangeError, core->toErrorString(index), core->toErrorString(constantMnCount));
			AvmAssert(!"unhandled verify error");
		}

		Multiname m;
		parseMultiname(cpool_mn[index], m);

		Traits* t = getTraits(m, toplevel);
		if(m.isParameterizedType())
		{
			Traits* param_traits = resolveTypeName(m.getTypeParameter(), toplevel);
			t = resolveParameterizedType(toplevel, t, param_traits);
		}
		if (!t)
		{
			#ifdef AVMPLUS_VERBOSE
			if (!toplevel || !toplevel->verifyErrorClass())
				core->console << "class not found: " << m << " index=" << index << "\n";
			#endif
			if (toplevel)
				toplevel->throwVerifyError(kClassNotFoundError, core->toErrorString(&m));
			AvmAssert(!"unhandled verify error");
		}
		if (!allowVoid && t == VOID_TYPE)
		{
			if (toplevel)
				toplevel->throwVerifyError(kIllegalVoidError);
			AvmAssert(!"unhandled verify error");
		}

		return t;
	}
示例#6
0
文件: AbcData.cpp 项目: changm/tessa
        uint32_t SlotOffsetsAndAsserts::getSlotOffset(Traits* t, int nameId)
        {
            Multiname name;
            t->pool->parseMultiname(name, nameId);
            if (name.isNsset())
                name.setNamespace(name.getNsset()->nsAt(0));

            AvmAssert(!name.isNsset());

            const TraitsBindings* tb = t->getTraitsBindings();
            Binding b = tb->findBinding(name.getName(), name.getNamespace());
            AvmAssert(AvmCore::isSlotBinding(b));
            int slotId = AvmCore::bindingToSlotId(b);
            return tb->getSlotOffset(slotId);
        }
	void PoolObject::resolveQName(uint32_t index, Multiname &m, const Toplevel* toplevel) const
	{
		if (index == 0 || index >= constantMnCount)
		{
			if (toplevel)
				toplevel->throwVerifyError(kCpoolIndexRangeError, core->toErrorString(index), core->toErrorString(constantMnCount));
			AvmAssert(!"unhandled verify error");
		}

		parseMultiname(cpool_mn[index], m);
		if (!m.isQName())
		{
			if (toplevel)
				toplevel->throwVerifyError(kCpoolEntryWrongTypeError, core->toErrorString(index));
			AvmAssert(!"unhandled verify error");
		}
	}
示例#8
0
	bool NativeInitializer::getCompiledInfo(NativeMethodInfo *info, Multiname &returnTypeName, uint32_t i) const
	{
		info->thunker = (AvmThunkNativeThunker)0;

		if (i < compiledMethodCount && compiledMethods[i])
		{
			bool isNumberRetType = false;
			if (NUMBER_TYPE) {
				Multiname numberTypeName(NUMBER_TYPE->ns(), NUMBER_TYPE->name());
				isNumberRetType = returnTypeName.matches(&numberTypeName);
			}
			info->thunker = isNumberRetType ? (AvmThunkNativeThunker)aotThunkerN : (AvmThunkNativeThunker)aotThunker;
			info->handler.function = compiledMethods[i];
			return true;
		}
		else
		{
			info->handler.function = (AvmThunkNativeFunctionHandler)0;
			return false;
		}
	}
	void PoolObject::parseMultiname(const byte *pos, Multiname& m) const
	{
		// the multiname has already been validated so we don't do
		// any checking here, we just fill in the Multiname object
		// with the information we have parsed.

		int index;
		CPoolKind kind = (CPoolKind) *(pos++);
        switch (kind)
        {
		case CONSTANT_Qname: 
		case CONSTANT_QnameA:
		{
			// U16 namespace_index
            // U16 name_index
			// parse a multiname with one namespace (aka qname)

			index = AvmCore::readU30(pos);
			if (!index)
				m.setAnyNamespace();
			else
				m.setNamespace(getNamespace(index));

			index = AvmCore::readU30(pos);
			if (!index)
				m.setAnyName();
			else
				m.setName(getString(index));

			m.setQName();
			m.setAttr(kind==CONSTANT_QnameA);
			break;
		}

		case CONSTANT_RTQname:
		case CONSTANT_RTQnameA: 
		{
			// U16 name_index
			// parse a multiname with just a name; ns fetched at runtime

			index = AvmCore::readU30(pos);
			if (!index)
				m.setAnyName();
			else
				m.setName(getString(index));

			m.setQName();
			m.setRtns();
			m.setAttr(kind==CONSTANT_RTQnameA);
			break;
		}

		case CONSTANT_RTQnameL:
		case CONSTANT_RTQnameLA:
		{
			m.setQName();
			m.setRtns();
			m.setRtname();
			m.setAttr(kind==CONSTANT_RTQnameLA);
			break;
		}

		case CONSTANT_Multiname:
		case CONSTANT_MultinameA:
		{
			index = AvmCore::readU30(pos);
			if (!index)
				m.setAnyName();
			else
				m.setName(getString(index));

			index = AvmCore::readU30(pos);
			AvmAssert(index != 0);
			m.setNsset(getNamespaceSet(index));

			m.setAttr(kind==CONSTANT_MultinameA);
			break;
		}

		case CONSTANT_MultinameL:
		case CONSTANT_MultinameLA:
		{
			m.setRtname();

			index = AvmCore::readU30(pos);
			AvmAssert(index != 0);
			m.setNsset(getNamespaceSet(index));

			m.setAttr(kind==CONSTANT_MultinameLA);
			break;
		}

		case CONSTANT_TypeName:
		{
			index = AvmCore::readU30(pos);
			Atom a = cpool_mn[index];
			parseMultiname(atomToPos(a), m);
			index = AvmCore::readU30(pos);
			AvmAssert(index==1);
			m.setTypeParameter(AvmCore::readU30(pos));
			break;
		}
		
		default:
			AvmAssert(false);
		}

		return;
	}
示例#10
0
    double SamplerScript::_getInvocationCount(ScriptObject* self, Atom a, QNameObject* qname, uint32_t type)
    {
#ifdef DEBUGGER
        AvmCore* core = self->core();
        Sampler* s = core->get_sampler();
        if (!s || !trusted(self))
            return -1;

        Multiname multiname;
        if(qname)
            qname->getMultiname(multiname);

        ScriptObject* object = self->toplevel()->global();
        if(!AvmCore::isObject(a))
        {
            // not sure if this will be true for standalone avmplus
            AvmAssert(core->codeContext() != NULL);
            DomainEnv *domainEnv = core->codeContext()->domainEnv();
            ScriptEnv* script = (ScriptEnv*) core->domainMgr()->findScriptEnvInDomainEnvByMultiname(domainEnv, multiname);
            if (script != (ScriptEnv*)BIND_NONE)
            {
                if (script == (ScriptEnv*)BIND_AMBIGUOUS)
                    self->toplevel()->throwReferenceError(kAmbiguousBindingError, &multiname);

                object = script->global;
                if (object == NULL)
                {
                    object = script->initGlobal();
                    script->coerceEnter(script->global->atom());
                }
            }
        }
        else
        {
            object = AvmCore::atomToScriptObject(a);

            if(AvmCore::istype(a, CLASS_TYPE) && !qname) {
                // return constructor count
                ClassClosure *cc = (ClassClosure*)object;
                if (cc->vtable->init) // Vector related crash here, Tommy says: I didn't think a type could ever not have a constructor but I guess there's no reason it has to.
                    return (double)cc->vtable->init->invocationCount();
            }
        }

        if(!object || !qname)
            return -1;

        VTable *v = object->vtable;

    again:

        MethodEnv *env = NULL;
        Binding b = self->toplevel()->getBinding(v->traits, &multiname);
        switch (AvmCore::bindingKind(b))
        {
        case BKIND_VAR:
        case BKIND_CONST:
        {
            // only look at slots for first pass, otherwise we're applying instance traits to the Class
            if(v == object->vtable) {
                Atom method = object->getSlotAtom(AvmCore::bindingToSlotId(b));
                if(AvmCore::isObject(method))
                {
                    env = AvmCore::atomToScriptObject(method)->getCallMethodEnv();
                }
            }
            break;
        }
        case BKIND_METHOD:
        {
            int m = AvmCore::bindingToMethodId(b);
            env = v->methods[m];
            break;
        }
        case BKIND_GET:
        case BKIND_GETSET:
        case BKIND_SET:
        {
            if(type == GET && AvmCore::hasGetterBinding(b))
                env = v->methods[AvmCore::bindingToGetterId(b)];
            else if(type == SET && AvmCore::hasSetterBinding(b))
                env = v->methods[AvmCore::bindingToSetterId(b)];
            break;
        }
        case BKIND_NONE:
        {
            Atom method = object->getStringProperty(multiname.getName());
            if(AvmCore::isObject(method))
            {
                env = AvmCore::atomToScriptObject(method)->getCallMethodEnv();
            }
            else if(v->ivtable)
            {
                v = v->ivtable;
                goto again;
            }
        }
        default:
            break;
        }

        if(env)
            return (double)env->invocationCount();
#else
        (void)self;
        (void)type;
        (void)qname;
        (void)a;
#endif

        return -1;
    }