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; }
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); }
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; }
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); }
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); } }
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); }
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); }