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 ABCClassInfo(int abcIndex) { m_abcIndex = abcIndex; // This will be set from init() m_ifaceNames = null !; // These will be set from initInstanceInfo and initStaticInfo m_instanceInit = null !; m_instanceTraits = null !; m_staticInit = null !; m_staticTraits = null !; }
private void _readScriptInfo() { int scriptCount = _readU30(); var scriptInfo = new ABCScriptInfo[scriptCount]; for (int i = 0; i < scriptCount; i++) { ABCMethodInfo init = m_abcFile.resolveMethodInfo(_readU30()); ABCTraitInfo[] traits = _readTraitInfo(_readU30()); scriptInfo[i] = new ABCScriptInfo(i, init, traits); } m_abcFile.setScriptInfo(scriptInfo); }
internal ABCMethodBodyInfo( int abcIndex, ABCMethodInfo methodInfo, int maxStack, int initScopeDepth, int maxScopeDepth, int localCount, byte[] code, ABCExceptionInfo[] exceptions, ABCTraitInfo[] activation ) { m_abcIndex = abcIndex; m_methodInfo = methodInfo; m_maxStack = maxStack; m_initScopeDepth = initScopeDepth; m_maxScopeDepth = maxScopeDepth; m_localCount = localCount; m_code = code; m_exceptions = exceptions; m_activation = activation; }
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); }
internal ABCScriptInfo(int abcIndex, ABCMethodInfo init, ABCTraitInfo[] traits) { m_abcIndex = abcIndex; m_init = init; m_traits = traits; }