Ejemplo n.º 1
0
        private TypeTree FixTypeTree(TypeTree typeTree, Symbol type, UserTypeFactory factory)
        {
            // Check basic type
            BasicTypeTree basicTypeTree = typeTree as BasicTypeTree;

            if (basicTypeTree != null)
            {
                // Basic type tree is not challenged against template arguments, so try to do that.
                UserType basicUserType;

                if (CreateFactory(factory).GetUserType(type, out basicUserType))
                {
                    TypeTree tree = UserTypeTree.Create(basicUserType, factory);

                    if (tree != null)
                    {
                        return(tree);
                    }
                }

                // Failed to match the type
                // TODO: Look for typedeclared. Class is using different types than in template specialization. We cannot support it right now.
                return(new VariableTypeTree());
            }

            // Check array type
            ArrayTypeTree arrayTypeTree = typeTree as ArrayTypeTree;

            if (arrayTypeTree != null)
            {
                TypeTree elementTypeTree = FixTypeTree(arrayTypeTree.ElementType, type.ElementType, factory);

                if (elementTypeTree != arrayTypeTree.ElementType)
                {
                    return(new ArrayTypeTree(elementTypeTree));
                }

                return(arrayTypeTree);
            }

            // Check pointer type
            PointerTypeTree pointerTypeTree = typeTree as PointerTypeTree;

            if (pointerTypeTree != null)
            {
                TypeTree elementTypeTree = FixTypeTree(pointerTypeTree.ElementType, type.ElementType, factory);

                if (elementTypeTree != pointerTypeTree.ElementType)
                {
                    return(new PointerTypeTree(elementTypeTree));
                }

                return(pointerTypeTree);
            }

            return(typeTree);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Generates user type field based on the specified symbol field and all other fields that are prepared for this function.
        /// Do not use this function directly, unless you are calling it from overridden function.
        /// </summary>
        /// <param name="field">The symbol field.</param>
        /// <param name="fieldType">The field tree type.</param>
        /// <param name="factory">The user type factory.</param>
        /// <param name="simpleFieldValue">The code foe "simple field value" used when creating transformation.</param>
        /// <param name="gettingField">The code for getting field variable.</param>
        /// <param name="isStatic">if set to <c>true</c> generated field should be static.</param>
        /// <param name="generationFlags">The user type generation flags.</param>
        /// <param name="extractingBaseClass">if set to <c>true</c> user type field is being generated for getting base class.</param>
        protected override UserTypeField ExtractFieldInternal(SymbolField field, TypeTree fieldType, UserTypeFactory factory, string simpleFieldValue, string gettingField, bool isStatic, UserTypeGenerationFlags generationFlags, bool extractingBaseClass)
        {
            // Physical code generation make sense only for non-static fields
            if (!isStatic)
            {
                bool lazyCacheUserTypeFields = generationFlags.HasFlag(UserTypeGenerationFlags.LazyCacheUserTypeFields);

                bool                   cacheUserTypeFields       = generationFlags.HasFlag(UserTypeGenerationFlags.CacheUserTypeFields);
                bool                   cacheStaticUserTypeFields = generationFlags.HasFlag(UserTypeGenerationFlags.CacheStaticUserTypeFields);
                string                 constructorText           = "";
                string                 fieldName          = field.Name;
                string                 fieldTypeString    = fieldType.GetTypeString();
                BasicTypeTree          baseType           = fieldType as BasicTypeTree;
                ArrayTypeTree          codeArrayType      = fieldType as ArrayTypeTree;
                UserTypeTree           userType           = fieldType as UserTypeTree;
                TransformationTypeTree transformationType = fieldType as TransformationTypeTree;
                bool                   isEmbedded         = field.Type.Tag != CodeTypeTag.Pointer;

                // Specialization for basic types
                if (baseType != null)
                {
                    if (baseType.BasicType == "string")
                    {
                        int charSize = field.Type.ElementType.Size;

                        constructorText = string.Format("ReadString(GetCodeType().Module.Process, ReadPointer(memoryBuffer, memoryBufferOffset + {0}, {1}), {2})", field.Offset, field.Type.Size, charSize);
                    }
                    else if (baseType.BasicType != "NakedPointer")
                    {
                        if (field.LocationType == LocationType.BitField)
                        {
                            constructorText = string.Format("Read{0}(memoryBuffer, memoryBufferOffset + {1}, {2}, {3})", baseType.GetTypeString().UppercaseFirst(), field.Offset, field.Size, field.BitPosition);
                        }
                        else
                        {
                            constructorText = string.Format("Read{0}(memoryBuffer, memoryBufferOffset + {1})", baseType.GetTypeString().UppercaseFirst(), field.Offset);
                        }
                    }
                }
                // Specialization for arrays
                else if (codeArrayType != null)
                {
                    if (codeArrayType.ElementType is BasicTypeTree)
                    {
                        baseType = (BasicTypeTree)codeArrayType.ElementType;
                        if (baseType != null && baseType.BasicType != "string" && baseType.BasicType != "NakedPointer")
                        {
                            int arraySize   = field.Type.Size;
                            int elementSize = field.Type.ElementType.Size;

                            if (baseType.BasicType == "char")
                            {
                                constructorText = string.Format("Read{0}Array(memoryBuffer, memoryBufferOffset + {1}, {2}, {3})", baseType.GetTypeString().UppercaseFirst(), field.Offset, arraySize / elementSize, elementSize);
                            }
                            else
                            {
                                constructorText = string.Format("Read{0}Array(memoryBuffer, memoryBufferOffset + {1}, {2})", baseType.GetTypeString().UppercaseFirst(), field.Offset, arraySize / elementSize);
                            }
                            fieldTypeString = baseType.GetTypeString() + "[]";
                        }
                    }
                }
                // Specialization for user types
                else if (userType != null && !extractingBaseClass)
                {
                    if (!(userType.UserType is EnumUserType))
                    {
                        string thisClassCodeType;

                        if (IsTypeUsingStaticCodeType(this))
                        {
                            thisClassCodeType = ClassCodeType;
                        }
                        else
                        {
                            thisClassCodeType = "thisClass.Value.GetCodeType()";
                            usedThisClass     = true;
                        }

                        // Check if type is embedded
                        if (!isEmbedded)
                        {
                            // If user type is not embedded, we do have pointer inside of our memory buffer that we can read directly
                            if (IsTypeUsingStaticCodeType(this))
                            {
                                constructorText = string.Format("ReadPointer<{0}>({4}, \"{1}\", memoryBuffer, memoryBufferOffset + {2}, {3})", fieldTypeString, fieldName, field.Offset, field.Type.Size, ClassCodeType);
                            }
                            else
                            {
                                constructorText = string.Format("ReadPointer<{0}>(thisClass, \"{1}\", memoryBuffer, memoryBufferOffset + {2}, {3})", fieldTypeString, fieldName, field.Offset, field.Type.Size);
                                usedThisClass   = true;
                            }

                            // Do downcasting if field has vtable
                            if (userType.UserType.Symbol.HasVTable() && userType.UserType.DerivedClasses.Count > 0)
                            {
                                constructorText += ".DowncastObject()";
                            }
                        }
                        else
                        {
                            // If user type is embedded, we can reuse memory buffer that we already have in this class
                            string fieldAddress  = string.Format("memoryBufferAddress + (ulong)(memoryBufferOffset + {0})", field.Offset);
                            string fieldCodeType = string.Format("{0}.GetClassFieldType(\"{1}\")", thisClassCodeType, fieldName);

                            if (IsTypeUsingStaticCodeType(userType.UserType))
                            {
                                fieldCodeType = string.Format("{0}.{1}", userType.UserType.FullClassName, ClassCodeType);
                            }
                            else if (IsTypeUsingStaticCodeType(this))
                            {
                                fieldCodeType = AddFieldCodeType(fieldName);
                            }

                            constructorText = string.Format("new {0}(memoryBuffer, memoryBufferOffset + {1}, memoryBufferAddress, {2}, {3}, \"{4}\")", fieldTypeString, field.Offset, fieldCodeType, fieldAddress, fieldName);
                        }
                    }
                    else
                    {
                        // TODO: This is enum. Read how much enum base type is big and just cast to enum type...
                    }
                }
                // Specialization for transformations
                else if (transformationType != null)
                {
                    if (!isEmbedded)
                    {
                        string thisClassCodeType;

                        if (IsTypeUsingStaticCodeType(this))
                        {
                            thisClassCodeType = ClassCodeType;
                        }
                        else
                        {
                            thisClassCodeType = "thisClass.Value.GetCodeType()";
                            usedThisClass     = true;
                        }

                        string fieldAddress  = string.Format("memoryBufferAddress + (ulong)(memoryBufferOffset + {0})", field.Offset);
                        string fieldVariable = string.Format("Variable.CreateNoCast({0}.GetClassFieldType(\"{1}\"), {2}, \"{1}\")", thisClassCodeType, fieldName, fieldAddress);

                        if (transformationType.Transformation.Transformation.HasPhysicalConstructor)
                        {
                            fieldVariable = string.Format("{0}, memoryBuffer, memoryBufferOffset + {1}, memoryBufferAddress", fieldVariable, field.Offset);
                        }

                        simpleFieldValue = fieldVariable;
                        constructorText  = string.Format("new {0}({1})", fieldTypeString, fieldVariable);
                    }
                }

                // If we found suitable physical representation, generate the field
                if (!string.IsNullOrEmpty(constructorText))
                {
                    return new UserTypeField()
                           {
                               ConstructorText      = constructorText,
                               FieldName            = "_" + fieldName,
                               FieldType            = fieldTypeString,
                               FieldTypeInfoComment = string.Format("// {0} {1};", field.Type.Name, fieldName),
                               PropertyName         = UserTypeField.GetPropertyName(field, this),
                               Static           = isStatic,
                               UseUserMember    = lazyCacheUserTypeFields,
                               CacheResult      = cacheUserTypeFields || (isStatic && cacheStaticUserTypeFields),
                               SimpleFieldValue = simpleFieldValue,
                           }
                }
                ;
            }

            return(base.ExtractFieldInternal(field, fieldType, factory, simpleFieldValue, gettingField, isStatic, generationFlags, extractingBaseClass));
        }