Example #1
0
	Atom FunctionObject::get_coerced_receiver(Atom a)
	{
		if (AvmCore::isNullOrUndefined(a))
		{
			// use callee's global object as this.
			// see E3 15.3.4.4
			a = _call->scope()->getScope(0);
		}
		MethodSignaturep ms = _call->method->getMethodSignature();
		return toplevel()->coerce(a, ms->paramTraits(0));
	}
Example #2
0
	static bool hasTypedArgs(MethodSignaturep ms)
	{
		int32_t param_count = ms->param_count();
		for (int32_t i = 1; i <= param_count; i++) {
			if (ms->paramTraits(i) != NULL) {
				// at least one parameter is typed; need full coerceEnter
				return true;
			}
		}
		return false;
	}
Example #3
0
    ScriptObject* TypeDescriber::describeTraits(Traitsp traits, uint32_t flags, Toplevel* toplevel)
    {
        if (!(flags & INCLUDE_TRAITS))
            return NULL;

        AvmCore* core = m_toplevel->core();
        GC* gc = core->GetGC();
        TraitsBindingsp tb = traits->getTraitsBindings();
        TraitsMetadatap tm = traits->getTraitsMetadata();

        ScriptObject* o = new_object();

        ArrayObject* bases = NULL;
        ArrayObject* metadata = NULL;
        ArrayObject* interfaces = NULL;
        ArrayObject* methods = NULL;
        ArrayObject* accessors = NULL;
        ArrayObject* variables = NULL;
        ScriptObject* constructor = NULL;

        if (flags & INCLUDE_METADATA)
        {
            metadata = new_array();
            PoolObject* class_mdpool;
            const uint8_t* class_md = tm->getMetadataPos(class_mdpool);
            if (class_md)
                addDescribeMetadata(metadata, class_mdpool, class_md);
        }

        if (flags & INCLUDE_BASES)
        {
            bases = new_array();
            for (Traitsp b = traits->base; b; b = b->base)
                pushstr(bases, describeClassName(b));
        }

        if (flags & INCLUDE_INTERFACES)
        {
            interfaces = new_array();
            for (InterfaceIterator iter(traits); iter.hasNext();)
            {
                Traits* ti = iter.next();
                pushstr(interfaces, describeClassName(ti));
            }
        }

        // constructor
        if (flags & INCLUDE_CONSTRUCTOR)
        {
            MethodInfo* initMethod = traits->init;
            if (initMethod)
            {
                initMethod->resolveSignature(toplevel);
                MethodSignaturep ms = initMethod->getMethodSignature();
                if (ms->param_count() > 0)
                {
                    constructor = describeParams(initMethod, ms);
                }
            }
        }

        if (flags & (INCLUDE_ACCESSORS | INCLUDE_METHODS | INCLUDE_VARIABLES))
        {
            // recover slot/method metadata and method-declarer information.

            // make a flattened set of bindings so we don't have to check for overrides as we go.
            // This is not terribly efficient, but doesn't need to be.
            MultinameBindingHashtable* mybind = MultinameBindingHashtable::create(gc);
            addBindings(m_toplevel->core(), mybind, tb, flags);

            // Don't want interface methods, so post-process and wipe out any
            // bindings that were added.
            for (InterfaceIterator ifc_iter(traits); ifc_iter.hasNext();)
            {
                Traitsp ti = ifc_iter.next();
                TraitsBindingsp tbi = ti->getTraitsBindings();
                StTraitsBindingsIterator iter(tbi);
                while (iter.next())
                {
                    if (!iter.key()) continue;
                    mybind->add(iter.key(), iter.ns(), BIND_NONE);
                }
            }

            // yuck, replicate buggy behavior in FP9/10
            RCList<Namespace> nsremoval(gc, kListInitialCapacity);
            if (flags & HIDE_NSURI_METHODS)
            {
                for (TraitsBindingsp tbi = tb->base; tbi; tbi = tbi->base)
                {
                    StTraitsBindingsIterator iter(tbi);
                    while (iter.next())
                    {
                        if (!iter.key()) continue;
                        Namespacep ns = iter.ns();
                        if (ns->getURI()->length() > 0 && nsremoval.indexOf(ns) < 0)
                        {
                            nsremoval.add(ns);
                        }
                    }
                }
            }

            StMNHTBindingIterator iter(mybind);
            while (iter.next())
            {
                if (!iter.key()) continue;
                Stringp name = iter.key();
                Namespacep ns = iter.ns();
                Binding binding = iter.value();
                Stringp nsuri = ns->getURI();
                TraitsMetadata::MetadataPtr md1 = NULL;
                TraitsMetadata::MetadataPtr md2 = NULL;
                PoolObject* md1pool = NULL;
                PoolObject* md2pool = NULL;

                // We only display public members -- exposing private namespaces could compromise security.
                if (ns->getType() != Namespace::NS_Public) {
                    continue;
                }

                if ((flags & HIDE_NSURI_METHODS) && nsremoval.indexOf(ns) >= 0) {
                    continue;
                }
                ScriptObject* v = new_object();

                const BindingKind bk = AvmCore::bindingKind(binding);
                switch (bk)
                {
                    case BKIND_CONST:
                    case BKIND_VAR:
                    {
                        if (!(flags & INCLUDE_VARIABLES))
                            continue;

                        const uint32_t slotID = AvmCore::bindingToSlotId(binding);
                        const KVPair props[] = {
                            { kstrid_access, strAtom(str(bk == BKIND_CONST ? kstrid_readonly : kstrid_readwrite)) },
                            { kstrid_type, strAtom(describeClassName(tb->getSlotTraits(slotID))) },
                        };
                        setpropmulti(v, props, elem_count(props));
                        if (!variables) variables = new_array();
                        pushobj(variables, v);
                        md1 = tm->getSlotMetadataPos(slotID, md1pool);
                        break;
                    }

                    case BKIND_METHOD:
                    {
                        if (!(flags & INCLUDE_METHODS))
                            continue;

                        const uint32_t methodID = AvmCore::bindingToMethodId(binding);
                        MethodInfo* mi = tb->getMethod(methodID);
                        mi->resolveSignature(toplevel);
                        MethodSignaturep ms = mi->getMethodSignature();

                        Traitsp declaringTraits = mi->declaringTraits();

                        const KVPair props[] = {
                            { kstrid_declaredBy, strAtom(describeClassName(declaringTraits)) },
                            { kstrid_returnType, strAtom(describeClassName(ms->returnTraits())) },
                            { kstrid_parameters, objAtom(describeParams(mi, ms)) },
                        };
                        setpropmulti(v, props, elem_count(props));
                        if (!methods) methods = new_array();
                        pushobj(methods, v);
                        md1 = tm->getMethodMetadataPos(methodID, md1pool);
                        break;
                    }

                    case BKIND_GET:
                    case BKIND_SET:
                    case BKIND_GETSET:
                    {
                        if (!(flags & INCLUDE_ACCESSORS))
                            continue;

                        const uint32_t methodID = AvmCore::hasGetterBinding(binding) ?
                                                    AvmCore::bindingToGetterId(binding) :
                                                    AvmCore::bindingToSetterId(binding);

                        MethodInfo* mi = tb->getMethod(methodID);
                        mi->resolveSignature(toplevel);
                        MethodSignaturep ms = mi->getMethodSignature();

                        Traitsp declaringTraits = mi->declaringTraits();

                        // The verifier does not check the signature of a setter
                        // except when it is invoked.  We must be prepared for the
                        // case in which it has no arguments.
                        Traitsp accessorType;

                        if (AvmCore::hasGetterBinding(binding)) {
                            accessorType = ms->returnTraits();
                        } else {
                            // If setter is malformed, just use '*' as a placeholder.
                            accessorType = (ms->param_count() < 1) ? NULL : ms->paramTraits(1);
                        }

                        static const uint8_t bk2str[8] =
                        {
                            uint8_t(kstrid_emptyString),    // BKIND_NONE
                            uint8_t(kstrid_emptyString),    // BKIND_METHOD
                            uint8_t(kstrid_emptyString),    // BKIND_VAR
                            uint8_t(kstrid_emptyString),    // BKIND_CONST
                            uint8_t(kstrid_emptyString),    // unused
                            uint8_t(kstrid_readonly),       // BKIND_GET
                            uint8_t(kstrid_writeonly),      // BKIND_SET
                            uint8_t(kstrid_readwrite)       // BKIND_GETSET
                        };
                        const KVPair props[] = {
                            { kstrid_declaredBy, strAtom(describeClassName(declaringTraits)) },
                            { kstrid_access, strAtom(str(StringId(bk2str[bk]))) },
                            { kstrid_type, strAtom(describeClassName(accessorType)) },
                        };
                        setpropmulti(v, props, elem_count(props));
                        if (AvmCore::hasGetterBinding(binding))
                            md1 = tm->getMethodMetadataPos(AvmCore::bindingToGetterId(binding), md1pool);
                        if (AvmCore::hasSetterBinding(binding))
                            md2 = tm->getMethodMetadataPos(AvmCore::bindingToSetterId(binding), md2pool);
                        if (!accessors) accessors = new_array();
                        pushobj(accessors, v);
                        break;
                    }
                    case BKIND_NONE:
                        break;
                    default:
                        break;
                }

                ArrayObject* vm = NULL;
                if ((flags & INCLUDE_METADATA) && (md1 || md2))
                {
                    vm = new_array();
                    addDescribeMetadata(vm, md1pool, md1);
                    addDescribeMetadata(vm, md2pool, md2);
                }
                const KVPair props[] = {
                    { kstrid_name, strAtom(name) },
                    { kstrid_uri, strAtom(nsuri->length() == 0 ? NULL : nsuri) },
                    { kstrid_metadata, objAtom(vm) },
                };
                setpropmulti(v, props, elem_count(props));
            }
        }

        const KVPair props[] = {
            { kstrid_bases, objAtom(bases) },
            { kstrid_interfaces, objAtom(interfaces) },
            { kstrid_metadata, objAtom(metadata) },
            { kstrid_accessors, objAtom(accessors) },
            { kstrid_methods, objAtom(methods) },
            { kstrid_variables, objAtom(variables) },
            { kstrid_constructor, objAtom(constructor) },
        };
        setpropmulti(o, props, elem_count(props));

        return o;
    }