コード例 #1
0
ファイル: ABCParser.cs プロジェクト: jfd16/Mariana
        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);
        }
コード例 #2
0
ファイル: ABCParser.cs プロジェクト: jfd16/Mariana
        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);
            }
        }