예제 #1
0
        public virtual bool CalculateOffsets()
        {
            var Members = StructuredScope.IdentifierList;

            for (var i = 0; i < Members.Count; i++)
            {
                var MemVar = Members[i] as MemberVariable;
                if (MemVar != null)
                {
                    var Type = MemVar.TypeOfSelf.RealId as Type;

                    var Struct = Type as StructType;
                    if (Struct != null && !Struct.CalculateLayout())
                    {
                        return(false);
                    }

                    MemVar.Offset = DataStoring.AlignWithIncrease(VarSize, Type.Align);
                    VarSize       = MemVar.Offset + Type.Size;
                }
            }

            InstanceSize = Container.State.CalcPow2Size(VarSize);
            return(true);
        }
예제 #2
0
파일: Types.cs 프로젝트: bencz/Zinnia-lang
        public void CalcSize()
        {
            if (Lengths == null)
            {
                return;
            }

            var ValType = TypeOfValues;

            ElementSize = DataStoring.AlignWithIncrease(ValType.Size, ValType.Align);

            var Size = ElementSize;

            foreach (var e in Lengths)
            {
                Size *= e;
            }

            Pow2Size  = Container.State.CalcPow2Size(Size);
            this.Size = Pow2Size;
        }
예제 #3
0
        private PluginResult Evaluate(ref ExpressionNode Node)
        {
            var OpNode = Node as OpExpressionNode;
            var Op     = OpNode.Operator;
            var Ch     = OpNode.Children;

            var Dst = Ch[0] as ConstExpressionNode;
            var Src = Ch.Length > 1 ? Ch[1] as ConstExpressionNode : null;

            var AllLinkedNodes = new AutoAllocatedList <LinkedExprNode>();

            Node.GetLinkedNodes(ref AllLinkedNodes, true);

            if (Dst.Value is NullValue || (Src != null && Src.Value is NullValue))
            {
                if (Dst.Type.UnderlyingClassOrRealId is ClassType)
                {
                    if (Op == Operator.Equality || Op == Operator.Inequality)
                    {
                        var Value = Dst.Value is NullValue == Src.Value is NullValue;
                        var Ret   = Constants.GetBoolValue(Container, Value, Node.Code);
                        Ret.LinkedNodes.AddRange(AllLinkedNodes);

                        Node = Parent.NewNode(Ret);
                        return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                    }
                }

                if (Dst.Type.RealId is StringType)
                {
                    if (Op == Operator.Add)
                    {
                        var DstVal = Dst.Value is NullValue ? "" : Dst.String;
                        var SrcVal = Src.Value is NullValue ? "" : Src.String;
                        var Value  = DstVal + SrcVal;

                        var Ret = Constants.GetStringValue(Container, Value, Node.Code);
                        Ret.LinkedNodes.AddRange(AllLinkedNodes);

                        Node = Parent.NewNode(Ret);
                        return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                    }
                }

                throw new ApplicationException();
            }
            else
            {
                var DstType = Dst.Type;
                var SrcType = Src != null ? Src.Type : null;
                var SrcVal  = Src != null ? Src.Value : null;

                var Ret = Dst.Value.DoOperation(SrcVal, Op, Node.Type);
                if (Ret is IntegerValue && Node.CheckingMode == CheckingMode.Unchecked)
                {
                    var IRet = Ret as IntegerValue;
                    IRet.Value = DataStoring.WrapToType(IRet.Value, Node.Type);
                }

                Node = Ret.ToExpression(State, Node.Type, Node.Code);
                if (Node == null)
                {
                    return(PluginResult.Failed);
                }

                Node.LinkedNodes.AddRange(AllLinkedNodes);
                Node = Parent.NewNode(Node);
                return(Node == null ? PluginResult.Failed : PluginResult.Ready);
            }
        }
예제 #4
0
        public PluginResult NewOpNode(ref ExpressionNode Node)
        {
            var OpNode = Node as OpExpressionNode;
            var Op     = OpNode.Operator;
            var Ch     = OpNode.Children;

            // ------------------------------------------------------------------------------------
            if (Op == Operator.Reinterpret)
            {
                if (Ch[0] is ConstExpressionNode)
                {
#warning WARNING
                }

                return(PluginResult.Succeeded);
            }

            // ------------------------------------------------------------------------------------
            else if (Op == Operator.Tuple || Op == Operator.Array)
            {
                var Type = Node.Type.RealId as NonrefArrayType;
                if (Op != Operator.Array || (Type != null && Type.Lengths != null && !(Type.TypeOfValues is AutomaticType)))
                {
                    if (Ch.TrueForAll(x => x is ConstExpressionNode))
                    {
                        var Constants = Ch.Select(x => (x as ConstExpressionNode).Value);
                        var SValue    = new StructuredValue(Constants.ToList());
                        Node = Parent.NewNode(new ConstExpressionNode(Node.Type, SValue, Node.Code));
                        return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                    }
                }
            }

            // ------------------------------------------------------------------------------------
            else if (Op == Operator.Index)
            {
                if (Ch.TrueForAll(x => x is ConstExpressionNode))
                {
                    var ConstCh0    = Ch[0] as ConstExpressionNode;
                    var NonrefArray = Ch[0].Type.RealId as NonrefArrayType;
                    var Dimensions  = NonrefArray.Lengths;
                    var Position    = 0;
                    var MulBy       = 1;

                    for (var i = Dimensions.Length - 1; i >= 0; i--)
                    {
                        var CChip1 = Ch[i + 1] as ConstExpressionNode;
                        var Index  = CChip1.Integer;

                        if (Index < 0 || Index >= Dimensions[i])
                        {
                            State.Messages.Add(MessageId.IndexOutOfRange, CChip1.Code);
                            return(PluginResult.Failed);
                        }

                        Position += (int)Index * MulBy;
                        MulBy    *= Dimensions[i];
                    }

                    var RetValue = ConstCh0.Value.GetMember(Position);
                    var RetType  = NonrefArray.TypeOfValues;

                    Node = Parent.NewNode(new ConstExpressionNode(RetType, RetValue, Node.Code));
                    return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                }
            }

            // ------------------------------------------------------------------------------------
            else if (Op == Operator.Member)
            {
                var ConstCh0 = Ch[0] as ConstExpressionNode;
                var Member   = Ch[1] as IdExpressionNode;
                if (ConstCh0 != null && Member != null)
                {
                    if (ConstCh0.Value is StructuredValue || ConstCh0.Value is ZeroValue)
                    {
                        var SType       = ConstCh0.Type.UnderlyingStructureOrRealId as StructuredType;
                        var Members     = SType.StructuredScope.IdentifierList;
                        var MemberIndex = Members.IndexOf(Member.Identifier);
                        var RetValue    = ConstCh0.Value.GetMember(MemberIndex);
                        var RetType     = Member.Identifier.TypeOfSelf;

                        Node = Parent.NewNode(new ConstExpressionNode(RetType, RetValue, Node.Code));
                        return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                    }
                }
            }

            // ------------------------------------------------------------------------------------
            else if (Op == Operator.Cast)
            {
                var Child = Ch[0] as ConstExpressionNode;
                if (Child == null)
                {
                    return(PluginResult.Succeeded);
                }

                var To    = Expressions.GetIdentifier(Ch[1]);
                var RTo   = To.RealId as Type;
                var RFrom = Child.Type.RealId as Type;

                if (Child.Value is NullValue || RFrom is AutomaticType)
                {
                    var OldNode = Node;
                    if ((Node = Node.DetachChild(0)) == null)
                    {
                        return(PluginResult.Failed);
                    }

                    Node.Type   = OldNode.Type;
                    Node.Flags |= ExpressionFlags.FixedType;
                    return(PluginResult.Ready);
                }

                Predicate <Identifier> Func = x =>
                {
                    var Rx = x.RealId as Type;
                    if (Rx is PointerType || Rx is ReferenceType || Rx is PointerAndLength ||
                        ((Rx.TypeFlags & TypeFlags.ReferenceValue) != 0 && !(Rx is StringType)))
                    {
                        return(false);
                    }

                    return(true);
                };

                if (!Identifiers.ProcessTuple(RTo, Func))
                {
                    return(PluginResult.Succeeded);
                }

                if (RTo is TupleType && !(RFrom is TupleType))
                {
                    var TupleTo   = RTo as TupleType;
                    var ToMembers = TupleTo.StructuredScope.IdentifierList;
                    var TupleCh   = new ExpressionNode[ToMembers.Count];

                    for (var i = 0; i < ToMembers.Count; i++)
                    {
                        var ToType = ToMembers[i].Children[0];
                        var Value  = Child.Value.Convert(ToType);
                        if (Value == null)
                        {
                            var Params = new String[] { Child.Value.ToString(), ToType.Name.ToString() };
                            State.Messages.Add(MessageId.CannotConvertConst, Node.Code, Params);
                            return(PluginResult.Failed);
                        }

                        TupleCh[i] = Value.ToExpression(Parent, ToType, Node.Code);
                        if (TupleCh[i] == null)
                        {
                            return(PluginResult.Failed);
                        }
                    }

                    Node      = new OpExpressionNode(Operator.Tuple, TupleCh, Node.Code);
                    Node.Type = To;
                    Node      = Parent.NewNode(Node);
                    return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                }

                var Ret = Child.Value.Convert(RTo);
                if (Ret == null)
                {
                    var Params = new String[] { Child.Value.ToString(), To.Name.ToString() };
                    State.Messages.Add(MessageId.CannotConvertConst, Node.Code, Params);
                    return(PluginResult.Failed);
                }

                if (Ret is IntegerValue && Node.CheckingMode == CheckingMode.Unchecked)
                {
                    var IRet = Ret as IntegerValue;
                    IRet.Value = DataStoring.WrapToType(IRet.Value, RTo);
                }

                Node = Ret.ToExpression(Parent, To, Node.Code);
                return(Node == null ? PluginResult.Failed : PluginResult.Ready);
            }

            // ------------------------------------------------------------------------------------
            else if (Op == Operator.And || Op == Operator.Or)
            {
                var ConstIndex = Ch[0] is ConstExpressionNode ? 0 :
                                 (Ch[1] is ConstExpressionNode ? 1 : -1);

                if (ConstIndex != -1)
                {
                    var CNode = Ch[ConstIndex] as ConstExpressionNode;
                    var IsAnd = Op == Operator.And;

                    if (CNode.Bool == IsAnd)
                    {
                        Node = Node.DetachChild(1 - ConstIndex);
                        return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                    }

                    Node = Parent.NewNode(new ConstExpressionNode(Node.Type, new BooleanValue(!IsAnd), Node.Code));
                    return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                }
            }

            // ------------------------------------------------------------------------------------
            else if (Op == Operator.Condition)
            {
                var Condition = Ch[0] as ConstExpressionNode;
                if (Condition != null)
                {
                    Node = Condition.Bool ? Ch[1] : Ch[2];
                    return(PluginResult.Ready);
                }
            }

            // ------------------------------------------------------------------------------------
            else if (Op == Operator.Call)
            {
                var Res = NewCallOpNode(ref Node);
                if (Res != PluginResult.Succeeded)
                {
                    return(Res);
                }
            }

            // ------------------------------------------------------------------------------------
            else if (Operators.IsCalculable(Op))
            {
                if (Ch[0] is ConstExpressionNode && (Ch.Length == 1 || Ch[1] is ConstExpressionNode))
                {
                    return(Evaluate(ref Node));
                }

                if (Operators.IsReversible(Op) && Ch[0] is ConstExpressionNode &&
                    Identifiers.IsScalarOrVectorNumber(Ch[0].Type) && !(Ch[1] is ConstExpressionNode))
                {
                    OpNode.Swap();
                    Op = OpNode.Operator;
                }

                if (Op == Operator.Add || Op == Operator.Subract)
                {
                    var ConstCh1 = Ch[1] as ConstExpressionNode;
                    if (ConstCh1 != null && Identifiers.IsScalarOrVectorNumber(ConstCh1.Type))
                    {
                        if (Constants.CompareTupleValues(ConstCh1.Value, x => x.Double == 0))
                        {
                            Node = Node.DetachChild(0);
                            return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                        }

                        var OpCh0 = Ch[0] as OpExpressionNode;
                        if (OpCh0 != null)
                        {
                            var Ch0Op = OpCh0.Operator;
                            var Ch0Ch = OpCh0.Children;
                            if (Ch0Op == Operator.Add || Ch0Op == Operator.Subract)
                            {
                                var ConstIndex = -1;
                                if (Ch0Ch[0] is ConstExpressionNode)
                                {
                                    ConstIndex = 0;
                                }
                                else if (Ch0Ch[1] is ConstExpressionNode)
                                {
                                    ConstIndex = 1;
                                }

                                if (ConstIndex != -1)
                                {
                                    var ConstCh0Chx = Ch0Ch[ConstIndex] as ConstExpressionNode;
                                    var NewOp       = Op == Ch0Op ? Operator.Add : Operator.Subract;

                                    ExpressionNode[] NewCh; // For strings
                                    if (NewOp == Operator.Add)
                                    {
                                        NewCh = new ExpressionNode[] { ConstCh0Chx, Ch[1] }
                                    }
                                    ;
                                    else
                                    {
                                        NewCh = new ExpressionNode[] { Ch[1], ConstCh0Chx }
                                    };

                                    Ch[0] = OpCh0.Children[1 - ConstIndex];
                                    Ch[1] = Parent.NewNode(new OpExpressionNode(NewOp, NewCh, Node.Code));
                                    if (Ch[1] == null)
                                    {
                                        return(PluginResult.Failed);
                                    }
                                }
                            }
                        }
                    }
                }
                else if (Op == Operator.Multiply || Op == Operator.Divide)
                {
                    var ConstCh1 = Ch[1] as ConstExpressionNode;
                    if (ConstCh1 != null && Identifiers.IsScalarOrVectorNumber(ConstCh1.Type))
                    {
                        if (Constants.CompareTupleValues(ConstCh1.Value, x => x.Double == 1))
                        {
                            Node = Node.DetachChild(0);
                            return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                        }

                        if (Constants.CompareTupleValues(ConstCh1.Value, x => x.Double == 0) && Op == Operator.Multiply)
                        {
                            Node = Node.DetachChild(1);
                            return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                        }

                        var OpCh0 = Ch[0] as OpExpressionNode;
                        if (OpCh0 != null)
                        {
                            var Ch0Op = OpCh0.Operator;
                            var Ch0Ch = OpCh0.Children;
                            if (Ch0Op == Operator.Multiply || Ch0Op == Operator.Divide)
                            {
                                var ConstIndex = -1;
                                if (Ch0Ch[0] is ConstExpressionNode)
                                {
                                    ConstIndex = 0;
                                }
                                else if (Ch0Ch[1] is ConstExpressionNode)
                                {
                                    ConstIndex = 1;
                                }

                                if (ConstIndex != -1)
                                {
                                    var ConstCh0Chx = Ch0Ch[ConstIndex] as ConstExpressionNode;
                                    var NewOp       = Op == Ch0Op ? Operator.Multiply : Operator.Divide;
                                    var NewCh       = new ExpressionNode[] { Ch[1], ConstCh0Chx };

                                    Ch[0] = OpCh0.Children[1 - ConstIndex];
                                    Ch[1] = Parent.NewNode(new OpExpressionNode(NewOp, NewCh, Node.Code));
                                    if (Ch[1] == null)
                                    {
                                        return(PluginResult.Failed);
                                    }
                                }
                            }
                        }
                    }
                }
                else if (Operators.IsRelEquality(Op))
                {
                    if (Ch[0] is ConstExpressionNode && !(Ch[1] is ConstExpressionNode))
                    {
                        OpNode.Swap();
                        Op = OpNode.Operator;
                    }

                    var ConstCh1 = Ch[1] as ConstExpressionNode;
                    var Type     = Ch[0].Type != null ? Ch[0].Type.RealId : null;
                    if (Type is UnsignedType && ConstCh1 != null && ConstCh1.Integer == 0)
                    {
                        if (Op == Operator.GreaterEqual)
                        {
                            Node = Constants.GetBoolValue(Container, true, Node.Code);
                            return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                        }
                        else if (Op == Operator.Greater)
                        {
                            OpNode.Operator = Op = Operator.Inequality;
                        }
                        else if (Op == Operator.Less)
                        {
                            Node = Constants.GetBoolValue(Container, false, Node.Code);
                            return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                        }
                        else if (Op == Operator.LessEqual)
                        {
                            OpNode.Operator = Op = Operator.Equality;
                        }
                    }
                }

                if (Op == Operator.Subract && Ch[1] is ConstExpressionNode)
                {
                    var ConstCh1 = Ch[1] as ConstExpressionNode;
                    if (ConstCh1 != null && ConstCh1.Type.RealId is NumberType && ConstCh1.CDouble < 0.0)
                    {
                        var NewCh = new ExpressionNode[] { ConstCh1 };
                        Ch[1] = Parent.NewNode(new OpExpressionNode(Operator.Negation, NewCh, Node.Code));
                        if (Ch[1] == null)
                        {
                            return(PluginResult.Failed);
                        }

                        OpNode.Operator = Op = Operator.Add;
                    }
                }
            }

            return(PluginResult.Succeeded);
        }
예제 #5
0
        Identifier ReadIdentifer(IdContainer Container, Identifier Parent)
        {
            var IdScope = Container.GetParent <IdentifierScope>();

            if (IdScope == null || IdScope.Identifier != Parent)
            {
                throw new ApplicationException();
            }

            var IdPos = Reader.BaseStream.Position - BeginningPos;

            if (IdPos != ReadLEB128_Long())
            {
                throw new InvalidAssemblyException();
            }

#warning CHECK
            var ParentIdRef = ReadLEB128_Int();

            var Byte           = Reader.ReadByte();
            var DeclaredIdType = (DeclaredIdType)(Byte & 15);
            var Access         = (IdentifierAccess)(Byte >> 4);

            var FlagData       = Reader.ReadUInt16();
            var Flags          = (IdentifierFlags)FlagData & IdentifierFlags.All;
            var HasName        = (FlagData & 16384) != 0;
            var HasOverloads   = (FlagData & 32768) != 0;
            var HasSpecialName = (Flags & IdentifierFlags.SpecialName) != 0;

            var Name         = HasName ? new CodeString(ReadLEB128_String()) : new CodeString();
            var AssemblyName = HasSpecialName ? ReadLEB128_String() : null;

            var StructuredScope = Container as StructuredScope;
            var IsGlobal        = (Flags & IdentifierFlags.Static) != 0 || !(Container.RealContainer is StructuredScope);

            var Ret = (Identifier)null;
            if (DeclaredIdType == DeclaredIdType.Alias)
            {
                Ret = new IdentifierAlias(Container, Name, null);
                ReadReference(Ret, ReferenceDestination.RealId, -1);
                UpdateList.Add(Ret);
            }
            else if (DeclaredIdType == DeclaredIdType.Class || DeclaredIdType == DeclaredIdType.Struct)
            {
                StructuredType Structured;
                if (DeclaredIdType == DeclaredIdType.Class)
                {
                    Ret = Structured = new ClassType(Container, Name);
                }
                else
                {
                    Ret = Structured = new StructType(Container, Name);
                }

                Structured.InstanceSize = ReadLEB128_Int();
                if (Structured.InstanceSize <= 0)
                {
                    throw new InvalidAssemblyException("Invalid size");
                }

                Structured.Align            = ReadLEB128_Int();
                Structured.LayoutCalculated = true;
                if (!DataStoring.VerifyAlign(Structured.Align))
                {
                    throw new InvalidAssemblyException("Invalid alingment");
                }

                if (DeclaredIdType == DeclaredIdType.Struct)
                {
                    Structured.Size = Structured.InstanceSize;
                }

                Structured.Guid = ReadGuid();
                var BaseCount = ReadLEB128_Int();
                Structured.BaseStructures = new StructureBase[BaseCount];
                for (var i = 0; i < BaseCount; i++)
                {
                    ReadReferenceDeclared(Structured, ReferenceDestination.Base, i);
                }

                Structured.FunctionTableIndex = ReadLEB128_Int();
                var Scope = new StructuredScope(Container, new CodeString(), Structured);
                Container.Children.Add(Scope);
                Structured.StructuredScope = Scope;
                ReadIdList(Scope, Structured);
                UpdateList.Add(Ret);
            }
            else if (DeclaredIdType == DeclaredIdType.Enum || DeclaredIdType == DeclaredIdType.Flag)
            {
                EnumType Enum;
                if (DeclaredIdType == Zinnia.DeclaredIdType.Enum)
                {
                    Ret = Enum = new EnumType(Container, Name, new CodeString());
                }
                else
                {
                    Ret = Enum = new FlagType(Container, Name, new CodeString());
                }
                ReadReference(Enum, ReferenceDestination.Children, 0);

                var Scope = new EnumScope(Container, new CodeString(), Enum);
                Container.Children.Add(Scope);
                Enum.EnumScope = Scope;

                var MemberCount = ReadLEB128_Int();
                if (MemberCount != 0)
                {
                    if (MemberCount < 0)
                    {
                        throw new InvalidAssemblyException();
                    }

                    for (var i = 0; i < MemberCount; i++)
                    {
                        var ConstName = new CodeString(ReadLEB128_String());
                        if (!ConstName.IsValidIdentifierName)
                        {
                            throw new InvalidAssemblyException("Invalid identifier name");
                        }

                        if (Identifiers.IsDefined(Scope.IdentifierList, ConstName.ToString()))
                        {
                            throw new InvalidAssemblyException("Identifier already defined");
                        }

                        var Const = new ConstVariable(Container, ConstName, Enum, ReadConst());
                        Scope.IdentifierList.Add(Const);
                    }
                }

                UpdateList.Add(Enum);
            }
            else if (DeclaredIdType == DeclaredIdType.Function || DeclaredIdType == DeclaredIdType.Constructor)
            {
                Function          Function;
                FunctionOverloads Overloads;
                if (DeclaredIdType == Zinnia.DeclaredIdType.Function)
                {
                    Overloads = Container.GetOverload(Name.ToString());
                    if (IsGlobal)
                    {
                        Ret = Function = new Function(Container, Name, null, Overloads);
                    }
                    else
                    {
                        Ret = Function = new MemberFunction(Container, Name, null, Overloads);
                    }
                }
                else
                {
                    if (HasName)
                    {
                        throw new InvalidAssemblyException("Constructors cannot have name");
                    }
                    if (StructuredScope == null)
                    {
                        throw new InvalidAssemblyException("Invalid container");
                    }

                    if (StructuredScope.ConstructorOverloads == null)
                    {
                        StructuredScope.ConstructorOverloads = new FunctionOverloads(null);
                    }

                    Overloads = StructuredScope.ConstructorOverloads;
                    Ret       = Function = new Constructor(Container, null, Overloads, new CodeString());
                }

                ReadReference(Function, ReferenceDestination.Children, 0);

                var OverloadIndex = HasOverloads ? ReadLEB128_Int() : 0;
                for (var i = 0; i < Overloads.Functions.Count; i++)
                {
                    var OverloadFunc = Overloads.Functions[i];
                    if (OverloadFunc.OverloadIndex == OverloadIndex)
                    {
                        throw new InvalidAssemblyException("Function with the same overload index");
                    }

                    /*
                     * if (Function.AreParametersSame(OverloadFunc))
                     *  throw new InvalidAssemblyException("Function with the same name and parameters");*/
                }

                Function.OverloadIndex = OverloadIndex;
                Overloads.Functions.Add(Function);

                if ((Flags & IdentifierFlags.Virtual) != 0)
                {
                    var MemberFunc = Function as MemberFunction;
                    MemberFunc.VirtualIndex = ReadLEB128_Int();
                    if ((Flags & IdentifierFlags.Override) != 0)
                    {
                        ReadReferenceDeclared(MemberFunc, ReferenceDestination.OverriddenId, -1);
                    }
                }

                Function.GlobalPointerIndex = ReadLEB128_Int();
            }
            else if (DeclaredIdType == DeclaredIdType.Destructor)
            {
                if (HasName)
                {
                    throw new InvalidAssemblyException("Destructors cannot have name");
                }
                if (StructuredScope == null)
                {
                    throw new InvalidAssemblyException("Invalid container");
                }

                var Function = new Destructor(Container, null, new CodeString());
                ReadReference(Function, ReferenceDestination.Children, 0);
                Function.GlobalPointerIndex = ReadLEB128_Int();
                Ret = Function;
            }
            else if (DeclaredIdType == DeclaredIdType.Variable)
            {
                if (IsGlobal)
                {
                    Ret = new GlobalVariable(Container, Name, null);
                }
                else
                {
                    Ret = new MemberVariable(Container, Name, null);
                }

                ReadReference(Ret, ReferenceDestination.Children, 0);

                if (!IsGlobal)
                {
                    var MemVar = Ret as MemberVariable;
                    MemVar.Offset = ReadLEB128_Int();
                }
                else
                {
                    var Global = Ret as GlobalVariable;
                    Global.GlobalPointerIndex = ReadLEB128_Int();
                }
            }
            else if (DeclaredIdType == DeclaredIdType.Constant)
            {
                var Const = new ConstVariable(Container, Name, null, null);
                ReadReference(Const, ReferenceDestination.Children, 0);
                Const.ConstInitValue = ReadConst();
                Ret = Const;
            }
            else if (DeclaredIdType == DeclaredIdType.Property)
            {
                var Property = new Property(Container, Name, (Type)null);
                var PScope   = new PropertyScope(Container, new CodeString(), Property);
                Container.Children.Add(PScope);
                Property.PropertyScope = PScope;
                ReadReference(Property, ReferenceDestination.Children, 0);
                ReadParameterReferences(Property);

                var Data = Reader.ReadByte();
                if ((Data & 1) != 0)
                {
                    PScope.Getter = ReadIdentifer(PScope, Property) as Function;
                }
                if ((Data & 2) != 0)
                {
                    PScope.Setter = ReadIdentifer(PScope, Property) as Function;
                }
                Ret = Property;
            }
            else if (DeclaredIdType == DeclaredIdType.Namespace)
            {
                var Scope = Container as NamespaceScope;
                if (Scope == null)
                {
                    throw new InvalidAssemblyException("Invalid container");
                }
                if (Access != IdentifierAccess.Public)
                {
                    throw new InvalidAssemblyException("Invalid access");
                }

                var Options = new GetIdOptions()
                {
                    Func = x => x is Namespace
                };
                var Namespace = Identifiers.GetMember(State, Parent, Name, Options) as Namespace;
                if (Namespace == null)
                {
                    Ret = Namespace = new Namespace(Container, Name);
                }

                var NewScope = new NamespaceScope(Container, new CodeString(), Namespace);
                Container.Children.Add(NewScope);
                Namespace.AddScope(NewScope);

                ReadIdList(NewScope, Namespace);
            }
            else
            {
                throw new InvalidAssemblyException("Invalid identifier type");
            }

            if (Ret != null)
            {
                if (HasSpecialName)
                {
                    Ret.AssemblyName = AssemblyName;
                }

                Ret.Access       = Access;
                Ret.Flags        = Flags;
                Ret.DescPosition = IdPos;
                CurrentAssembly.Ids.Add(IdPos, Ret);
            }

            return(Ret);
        }
예제 #6
0
        void ReadReference(LoaderReference Ref)
        {
            var NonDeclared = (UndeclaredIdType)Reader.ReadByte();

            if (NonDeclared == UndeclaredIdType.Unknown)
            {
                ReadReferenceDeclared(Ref);
                return;
            }

            Identifier NewId;
            var        Container = Ref.DstId.Container;

            if (NonDeclared == UndeclaredIdType.RefArrayType)
            {
                var Arr = new RefArrayType(Container, null, 0, false);
                ReadReference(Arr, ReferenceDestination.Children, 0);
                UpdateList.Add(Arr);

                Arr.Dimensions = ReadLEB128_Int();
                NewId          = Arr;
            }
            else if (NonDeclared == UndeclaredIdType.NonrefArrayType)
            {
                var Arr = new NonrefArrayType(Container, null, null, false);
                ReadReference(Arr, ReferenceDestination.Children, 0);
                UpdateList.Add(Arr);

                var Dimensions = ReadLEB128_Int();
                if (Dimensions != 0)
                {
                    var Lengths = new int[Dimensions];
                    for (var i = 0; i < Dimensions; i++)
                    {
                        Lengths[i] = ReadLEB128_Int();
                    }

                    Arr.Lengths    = Lengths;
                    Arr.Dimensions = Dimensions;
                }

                NewId = Arr;
            }
            else if (NonDeclared == UndeclaredIdType.Pointer)
            {
                NewId = new PointerType(Container, null, false);
                ReadReference(NewId, ReferenceDestination.Children, 0);
                UpdateList.Add(NewId);
            }
            else if (NonDeclared == UndeclaredIdType.Reference)
            {
                var Mode = (ReferenceMode)Reader.ReadByte();
                NewId = new ReferenceType(Container, null, Mode, false);
                ReadReference(NewId, ReferenceDestination.Children, 0);
                UpdateList.Add(NewId);
            }
            else if (NonDeclared == UndeclaredIdType.Tuple)
            {
                var Tuple = new TupleType(Container, (List <Identifier>)null);
                Tuple.InstanceSize = ReadLEB128_Int();
                if (Tuple.InstanceSize <= 0)
                {
                    throw new InvalidAssemblyException("Invalid size");
                }

                Tuple.Size             = Tuple.InstanceSize;
                Tuple.Align            = ReadLEB128_Int();
                Tuple.LayoutCalculated = true;
                if (!DataStoring.VerifyAlign(Tuple.Align))
                {
                    throw new InvalidAssemblyException("Invalid alignment");
                }

                var Named       = Reader.ReadBoolean();
                var MemberCount = ReadLEB128_Int();
                for (var i = 0; i < MemberCount; i++)
                {
                    var Name      = Named ? new CodeString(ReadLEB128_String()) : new CodeString();
                    var MemberVar = new MemberVariable(Tuple.StructuredScope, Name, null);
                    MemberVar.Access = IdentifierAccess.Public;
                    ReadReference(MemberVar, ReferenceDestination.Children, 0);
                    MemberVar.Offset = ReadLEB128_Int();
                    Tuple.StructuredScope.IdentifierList.Add(MemberVar);
                }

                UpdateList.Add(Tuple);
                NewId = Tuple;
            }
            else if (NonDeclared == UndeclaredIdType.PointerAndLength)
            {
                var PAndL = new PointerAndLength(Container, null, false);
                ReadReference(PAndL.PointerType, ReferenceDestination.Children, 0);
                UpdateList.Add(PAndL);
                NewId = PAndL;
            }
            else if (NonDeclared == UndeclaredIdType.NonstaticFunctionType)
            {
                var FType = new NonstaticFunctionType(Container, null, false);
                ReadReference(FType, ReferenceDestination.Children, 0);
                UpdateList.Add(FType);
                NewId = FType;
            }
            else if (NonDeclared == UndeclaredIdType.Function)
            {
                var Conv = (CallingConvention)Reader.ReadByte();
                NewId = new TypeOfFunction(Container, Conv, new Identifier[1], false);
                ReadReference(NewId, ReferenceDestination.Children, 0);

                ReadParameterReferences(NewId);
                UpdateList.Add(NewId);
            }
            else
            {
                NewId = Global.CommonIds.GetIdentifier(NonDeclared);
                if (NewId == null)
                {
                    throw new InvalidAssemblyException();
                }
            }

            SetReferencedId(Ref, NewId);
        }