Ejemplo n.º 1
0
 internal ABCExceptionInfo(
     int tryStart, int tryEnd, int catchTarget, ABCMultiname catchTypeName, ABCMultiname catchVarName)
 {
     m_tryStart      = tryStart;
     m_tryEnd        = tryEnd;
     m_catchTarget   = catchTarget;
     m_catchTypeName = catchTypeName;
     m_catchVarName  = catchVarName;
 }
Ejemplo n.º 2
0
        internal void _readMethodBodies()
        {
            int methodBodyCount = _readU30();
            var methodBodies    = new ABCMethodBodyInfo[methodBodyCount];

            for (int i = 0; i < methodBodies.Length; i++)
            {
                ABCMethodInfo methodInfo = m_abcFile.resolveMethodInfo(_readU30());

                int maxStack       = _readU30();
                int localCount     = _readU30();
                int initScopeDepth = _readU30();
                int maxScopeDepth  = _readU30();

                if (initScopeDepth > maxScopeDepth)
                {
                    throw ErrorHelper.createError(ErrorCode.MARIANA__ABC_METHOD_BODY_INVALID_SCOPE_DEPTHS, i);
                }

                int    codeSize = _readU30();
                byte[] code     = new byte[codeSize];

                _readBytesFromStream(code);

                int excBlockCount = _readU30();
                var excBlocks     = Array.Empty <ABCExceptionInfo>();

                if (excBlockCount != 0)
                {
                    excBlocks = new ABCExceptionInfo[excBlockCount];

                    for (int j = 0; j < excBlocks.Length; j++)
                    {
                        int start       = _readU30();
                        int end         = _readU30();
                        int catchTarget = _readU30();

                        // See AVM2 overview errata.
                        ABCMultiname errTypeName = m_abcFile.resolveMultiname(_readU30());
                        ABCMultiname errVarName  = m_abcFile.resolveMultiname(_readU30());

                        excBlocks[j] = new ABCExceptionInfo(start, end, catchTarget, errTypeName, errVarName);
                    }
                }

                ABCTraitInfo[] activationTraits = _readTraitInfo(_readU30());

                methodBodies[i] = new ABCMethodBodyInfo(
                    i, methodInfo, maxStack, initScopeDepth, maxScopeDepth, localCount, code, excBlocks, activationTraits);
            }

            m_abcFile.setMethodBodyInfo(methodBodies);
        }
Ejemplo n.º 3
0
 internal ABCMethodInfo(
     int abcIndex,
     ABCMultiname returnTypeName,
     string methodName,
     ABCMethodFlags flags,
     ABCMultiname[] paramTypeNames,
     string?[]?paramNames,
     ASAny[]?paramDefaultValues
     )
 {
     m_abcIndex           = abcIndex;
     m_paramTypeNames     = paramTypeNames;
     m_paramNames         = paramNames;
     m_paramDefaultValues = paramDefaultValues;
     m_returnTypeName     = returnTypeName;
     m_methodName         = methodName;
     m_flags = flags;
 }
Ejemplo n.º 4
0
        private ABCTraitInfo[] _readTraitInfo(int count)
        {
            const ABCTraitFlags validTraitAttrs =
                ABCTraitFlags.ATTR_Final | ABCTraitFlags.ATTR_Metadata | ABCTraitFlags.ATTR_Override;

            if (count == 0)
            {
                return(Array.Empty <ABCTraitInfo>());
            }

            var traits = new ABCTraitInfo[count];

            for (int i = 0; i < traits.Length; i++)
            {
                ABCMultiname traitName = m_abcFile.resolveMultiname(_readU30());
                if (traitName.kind != ABCConstKind.QName)
                {
                    throw ErrorHelper.createError(ErrorCode.MARIANA__ABC_CLASS_TRAIT_NAME_NOT_QNAME);
                }

                QName traitQualifiedName = new QName(
                    m_abcFile.resolveNamespace(traitName.namespaceIndex),
                    m_abcFile.resolveString(traitName.localNameIndex)
                    );

                if (traitQualifiedName.ns.kind == NamespaceKind.ANY || traitQualifiedName.localName == null)
                {
                    throw ErrorHelper.createError(ErrorCode.MARIANA__ABC_CLASS_TRAIT_NAME_NULL);
                }

                ABCTraitFlags flags = (ABCTraitFlags)_readU8();

                if ((flags & ~ABCTraitFlags.KIND_MASK & ~validTraitAttrs) != 0)
                {
                    throw ErrorHelper.createError(ErrorCode.INVALID_TRAIT_KIND, (int)flags);
                }

                ABCTraitFlags kind = flags & ABCTraitFlags.KIND_MASK;
                ABCTraitInfo  traitInfo;

                if (kind == ABCTraitFlags.Slot || kind == ABCTraitFlags.Const)
                {
                    int slotId = _readU30();

                    ABCMultiname typeName        = m_abcFile.resolveMultiname(_readU30());
                    ASAny        defaultVal      = ASAny.undefined;
                    int          defaultValIndex = _readU30();

                    if (defaultValIndex != 0)
                    {
                        defaultVal = m_abcFile.resolveConstant((ABCConstKind)_readU8(), defaultValIndex);
                    }

                    traitInfo = new ABCTraitInfo(traitQualifiedName, flags, slotId, typeName, defaultValIndex != 0, defaultVal);
                }
                else if (kind == ABCTraitFlags.Class)
                {
                    int          slotId    = _readU30();
                    ABCClassInfo classInfo = m_abcFile.resolveClassInfo(_readU30());
                    traitInfo = new ABCTraitInfo(traitQualifiedName, flags, slotId, classInfo);
                }
                else if (kind >= ABCTraitFlags.Method && kind <= ABCTraitFlags.Function)
                {
                    int           slotOrDispId = _readU30();
                    ABCMethodInfo methodInfo   = m_abcFile.resolveMethodInfo(_readU30());
                    traitInfo = new ABCTraitInfo(traitQualifiedName, flags, slotOrDispId, methodInfo);
                }
                else
                {
                    throw ErrorHelper.createError(ErrorCode.INVALID_TRAIT_KIND, (int)flags);
                }

                if ((flags & ABCTraitFlags.ATTR_Metadata) != 0)
                {
                    int metadataCount = _readU30();
                    if (metadataCount != 0)
                    {
                        MetadataTag[] metadata = new MetadataTag[metadataCount];

                        for (int j = 0; j < metadata.Length; j++)
                        {
                            metadata[j] = m_abcFile.resolveMetadata(_readU30());
                        }

                        traitInfo.setMetadata(new MetadataTagCollection(metadata));
                    }
                }

                traits[i] = traitInfo;
            }

            return(traits);
        }
Ejemplo n.º 5
0
        private void _readClassInfo()
        {
            const ABCClassFlags validClassFlags =
                ABCClassFlags.ClassFinal
                | ABCClassFlags.ClassSealed
                | ABCClassFlags.ClassInterface
                | ABCClassFlags.ClassProtectedNs;

            int classCount   = _readU30();
            var classInfoArr = new ABCClassInfo[classCount];

            // Since a class can refer to another via a class trait in its instance_info
            // or static_info traits, we must create all ABCClassInfo instances upfront.

            for (int i = 0; i < classInfoArr.Length; i++)
            {
                classInfoArr[i] = new ABCClassInfo(i);
            }

            m_abcFile.setClassInfo(classInfoArr);

            // Read instance_info

            for (int i = 0; i < classInfoArr.Length; i++)
            {
                ABCMultiname className = m_abcFile.resolveMultiname(_readU30());
                if (className.kind != ABCConstKind.QName)
                {
                    throw ErrorHelper.createError(ErrorCode.MARIANA__ABC_CLASS_TRAIT_NAME_NOT_QNAME);
                }

                QName classQualifiedName = new QName(
                    m_abcFile.resolveNamespace(className.namespaceIndex),
                    m_abcFile.resolveString(className.localNameIndex)
                    );

                if (classQualifiedName.ns.kind == NamespaceKind.ANY || classQualifiedName.localName == null)
                {
                    throw ErrorHelper.createError(ErrorCode.MARIANA__ABC_CLASS_TRAIT_NAME_NULL);
                }

                ABCMultiname parentName = m_abcFile.resolveMultiname(_readU30());

                var flags = (ABCClassFlags)_readU8();

                if ((flags & ~validClassFlags) != 0)
                {
                    throw ErrorHelper.createError(ErrorCode.MARIANA__ABC_INVALID_INSTANCE_INFO_FLAGS);
                }

                const ABCClassFlags finalOrInterface = ABCClassFlags.ClassFinal | ABCClassFlags.ClassInterface;
                if ((flags & finalOrInterface) == finalOrInterface)
                {
                    // ClassFinal and ClassInterface cannot be used together
                    throw ErrorHelper.createError(ErrorCode.MARIANA__ABC_INVALID_INSTANCE_INFO_FLAGS);
                }

                Namespace protectedNS = default(Namespace);
                if ((flags & ABCClassFlags.ClassProtectedNs) != 0)
                {
                    protectedNS = m_abcFile.resolveNamespace(_readU30());
                }

                int            interfaceCount = _readU30();
                ABCMultiname[] interfaceNames = Array.Empty <ABCMultiname>();

                if (interfaceCount != 0)
                {
                    interfaceNames = new ABCMultiname[interfaceCount];
                    for (int j = 0; j < interfaceNames.Length; j++)
                    {
                        interfaceNames[j] = m_abcFile.resolveMultiname(_readU30());
                    }
                }

                ABCMethodInfo  instanceInit = m_abcFile.resolveMethodInfo(_readU30());
                ABCTraitInfo[] traits       = _readTraitInfo(_readU30());

                classInfoArr[i].init(classQualifiedName, parentName, interfaceNames, protectedNS, flags);
                classInfoArr[i].initInstanceInfo(instanceInit, traits);
            }

            // Read class_info
            for (int i = 0; i < classCount; i++)
            {
                ABCMethodInfo  staticInit = m_abcFile.resolveMethodInfo(_readU30());
                ABCTraitInfo[] traits     = _readTraitInfo(_readU30());
                classInfoArr[i].initStaticInfo(staticInit, traits);
            }
        }
Ejemplo n.º 6
0
        private void _readMethodInfo()
        {
            const ABCMethodFlags validMethodFlags =
                ABCMethodFlags.NEED_REST
                | ABCMethodFlags.HAS_OPTIONAL
                | ABCMethodFlags.NEED_ACTIVATION
                | ABCMethodFlags.NEED_ARGUMENTS
                | ABCMethodFlags.SET_DXNS
                | ABCMethodFlags.HAS_PARAM_NAMES;

            int methodCount   = _readU30();
            var methodInfoArr = new ABCMethodInfo[methodCount];

            for (int i = 0; i < methodCount; i++)
            {
                int          paramCount  = _readU30();
                ABCMultiname retTypeName = m_abcFile.resolveMultiname(_readU30());

                ABCMultiname[] paramTypeNames = Array.Empty <ABCMultiname>();
                ASAny[]? defaultValues = null;
                string?[]? paramNames = null;

                if (paramCount != 0)
                {
                    paramTypeNames = new ABCMultiname[paramCount];
                    for (int j = 0; j < paramCount; j++)
                    {
                        paramTypeNames[j] = m_abcFile.resolveMultiname(_readU30());
                    }
                }

                string         methodName  = m_abcFile.resolveString(_readU30()) ?? "";
                ABCMethodFlags methodFlags = (ABCMethodFlags)_readU8();

                if ((methodFlags & ~validMethodFlags) != 0)
                {
                    throw ErrorHelper.createError(ErrorCode.METHOD_INFO_INVALID_FLAGS, i, (int)methodFlags);
                }

                // NEED_ARGUMENTS and NEED_REST cannot be set together.
                const ABCMethodFlags needArgumentsOrRest = ABCMethodFlags.NEED_ARGUMENTS | ABCMethodFlags.NEED_REST;
                if ((methodFlags & needArgumentsOrRest) == needArgumentsOrRest)
                {
                    throw ErrorHelper.createError(ErrorCode.METHOD_INFO_INVALID_FLAGS, i, (int)methodFlags);
                }

                if ((methodFlags & ABCMethodFlags.HAS_OPTIONAL) != 0)
                {
                    int optionCount = _readU30();

                    if (optionCount > paramCount)
                    {
                        throw ErrorHelper.createError(ErrorCode.MARIANA__ABC_METHOD_INFO_OPTIONAL_EXCEEDS_PARAM, i);
                    }

                    defaultValues = new ASAny[optionCount];
                    for (int j = 0; j < optionCount; j++)
                    {
                        int val  = _readU30();
                        var kind = (ABCConstKind)_readU8();
                        defaultValues[j] = m_abcFile.resolveConstant(kind, val);
                    }
                }

                if ((methodFlags & ABCMethodFlags.HAS_PARAM_NAMES) != 0)
                {
                    paramNames = new string?[paramCount];
                    for (int j = 0; j < paramNames.Length; j++)
                    {
                        paramNames[j] = m_abcFile.resolveString(_readU30());
                    }
                }

                methodInfoArr[i] = new ABCMethodInfo(
                    i, retTypeName, methodName, methodFlags, paramTypeNames, paramNames, defaultValues);
            }

            m_abcFile.setMethodInfo(methodInfoArr);
        }
Ejemplo n.º 7
0
        private void _readConstantPools()
        {
            int intPoolSize = _readU30();

            if (intPoolSize != 0)
            {
                intPoolSize--;
            }

            int[] intPool = new int[intPoolSize + 1];
            for (int i = 1; i < intPool.Length; i++)
            {
                intPool[i] = (int)_readU32();
            }

            m_abcFile.setIntPool(intPool);

            int uintPoolSize = _readU30();

            if (uintPoolSize != 0)
            {
                uintPoolSize--;
            }

            uint[] uintPool = new uint[uintPoolSize + 1];
            for (int i = 1; i < uintPool.Length; i++)
            {
                uintPool[i] = _readU32();
            }

            m_abcFile.setUintPool(uintPool);

            int doublePoolSize = _readU30();

            if (doublePoolSize != 0)
            {
                doublePoolSize--;
            }

            double[] doublePool = new double[doublePoolSize + 1];

            doublePool[0] = Double.NaN;
            for (int i = 1; i < doublePool.Length; i++)
            {
                doublePool[i] = _readD64();
            }

            m_abcFile.setDoublePool(doublePool);

            int stringPoolSize = _readU30();

            if (stringPoolSize != 0)
            {
                stringPoolSize--;
            }

            string?[] stringPool = new string?[stringPoolSize + 1];
            for (int i = 1; i < stringPool.Length; i++)
            {
                stringPool[i] = _readString();
            }

            m_abcFile.setStringPool(stringPool);

            int nsPoolSize = _readU30();

            if (nsPoolSize != 0)
            {
                nsPoolSize--;
            }

            Namespace[] nsPool = new Namespace[nsPoolSize + 1];
            for (int i = 1; i < nsPool.Length; i++)
            {
                nsPool[i] = _readNamespace();
            }

            m_abcFile.setNamespacePool(nsPool);

            int nsSetPoolSize = _readU30();

            if (nsSetPoolSize != 0)
            {
                nsSetPoolSize--;
            }

            NamespaceSet[] nsSetPool = new NamespaceSet[nsSetPoolSize + 1];

            for (int i = 1; i < nsSetPool.Length; i++)
            {
                int         setCount = _readU30();
                Namespace[] nsInSet  = new Namespace[setCount];
                for (int j = 0; j < nsInSet.Length; j++)
                {
                    Namespace ns = m_abcFile.resolveNamespace(_readU30());
                    if (ns.isPublic)
                    {
                        // Set the public namespace to be first in a set to improve runtime lookup performance
                        nsInSet[j] = nsInSet[0];
                        nsInSet[0] = ns;
                    }
                    else
                    {
                        nsInSet[j] = ns;
                    }
                }
                nsSetPool[i] = new NamespaceSet(nsInSet);
            }

            m_abcFile.setNamespaceSetPool(nsSetPool);

            int multinamePoolSize = _readU30();

            if (multinamePoolSize != 0)
            {
                multinamePoolSize--;
            }

            ABCMultiname[] multinamePool = new ABCMultiname[multinamePoolSize + 1];

            multinamePool[0] = new ABCMultiname(ABCConstKind.QName, 0, 0);
            for (int i = 1; i < multinamePool.Length; i++)
            {
                multinamePool[i] = _readMultiname();
            }

            m_abcFile.setMultinamePool(multinamePool);

            int genArgListPoolSize = m_genArgLists.length;

            ABCMultiname[][] genArgListPool = new ABCMultiname[genArgListPoolSize][];

            for (int i = 0; i < genArgListPool.Length; i++)
            {
                int[] argIndices = m_genArgLists[i];
                var   arglist    = new ABCMultiname[argIndices.Length];

                for (int j = 0; j < argIndices.Length; j++)
                {
                    arglist[j] = m_abcFile.resolveMultiname(argIndices[j]);
                }

                genArgListPool[i] = arglist;
            }

            m_abcFile.setGenericArgListPool(genArgListPool);
        }