Пример #1
0
 private static LNode EncodeTypeAndName(ITypeMember member, EncoderState state)
 {
     return(state.Factory.Call(
                CodeSymbols.Dot,
                state.Encode(member.ParentType),
                state.Encode(member.Name)));
 }
Пример #2
0
 private static IReadOnlyList <LNode> EncodeCall(CallPrototype value, EncoderState state)
 {
     return(new LNode[]
     {
         state.Encode(value.Callee),
         state.Encode(value.Lookup)
     });
 }
Пример #3
0
 /// <summary>
 /// Encodes a field as an LNode.
 /// </summary>
 /// <param name="value">The field to encode.</param>
 /// <param name="state">The encoder to use.</param>
 /// <returns>An LNode that represents the field.</returns>
 public static LNode Encode(IField value, EncoderState state)
 {
     return(state.Factory.Call(
                CodeSymbols.Var,
                state.Encode(value.Name),
                state.Encode(value.IsStatic),
                state.Encode(value.FieldType))
            .WithAttrs(
                new VList <LNode>(
                    state.Encode(value.Attributes))));
 }
 /// <inheritdoc/>
 public override LNode Encode(ITypeMember value, EncoderState state)
 {
     if (value is IField)
     {
         return(IrField.Encode((IField)value, state));
     }
     else
     {
         return(IrMethod.Encode((IMethod)value, state));
     }
 }
Пример #5
0
 /// <summary>
 /// Encodes an assembly as an LNode.
 /// </summary>
 /// <param name="value">The assembly to encode.</param>
 /// <param name="state">The encoder to use.</param>
 /// <returns>An LNode that represents the assembly.</returns>
 public static LNode Encode(IAssembly value, EncoderState state)
 {
     return(state.Factory.Call(
                CodeSymbols.Assembly,
                state.Encode(value.FullName),
                state.Factory.Call(
                    CodeSymbols.Braces,
                    value.Types.EagerSelect(state.EncodeDefinition)))
            .WithAttrs(
                new VList <LNode>(
                    state.Encode(value.Attributes))));
 }
Пример #6
0
 public override LNode Encode(IType value, EncoderState state)
 {
     if (typeParameters.Contains(value))
     {
         return(state.Factory.Call(
                    CodeSymbols.PreBangBang,
                    state.Encode(value.Name)));
     }
     else
     {
         return(typeCodec.Encode(value, state));
     }
 }
Пример #7
0
        /// <summary>
        /// Encodes a value.
        /// </summary>
        /// <param name="value">The value to encode.</param>
        /// <param name="state">The state of the encoder.</param>
        /// <returns>The encoded value.</returns>
        public override LNode Encode(TObj value, EncoderState state)
        {
            var valType = value.GetType();
            Func <TObj, EncoderState, LNode> encoder;

            try
            {
                specializedEncoderLock.EnterReadLock();
                if (!specializedEncoders.TryGetValue(valType, out encoder))
                {
                    encoder = null;
                }
            }
            finally
            {
                specializedEncoderLock.ExitReadLock();
            }

            if (encoder == null)
            {
                try
                {
                    specializedEncoderLock.EnterWriteLock();
                    Type encoderKey;

                    if (encoders.Keys.TryGetBestElement(
                            (t1, t2) => PickMostDerivedParent(t1, t2, valType),
                            out encoderKey) &&
                        encoderKey != null &&
                        encoderKey.IsAssignableFrom(valType))
                    {
                        encoder = encoders[encoderKey];
                        specializedEncoders[valType] = encoder;
                    }
                }
                finally
                {
                    specializedEncoderLock.ExitWriteLock();
                }
            }

            return(encoder(value, state));
        }
Пример #8
0
        /// <summary>
        /// Encodes a method as an LNode.
        /// </summary>
        /// <param name="value">The method to encode.</param>
        /// <param name="state">The encoder to use.</param>
        /// <returns>An LNode that represents the method.</returns>
        public static LNode Encode(IMethod value, EncoderState state)
        {
            var typeParamsNode = state.Factory.Call(
                CodeSymbols.AltList,
                value.GenericParameters
                .Select(state.EncodeDefinition)
                .ToList());

            var parameterNodes = state.Factory.Call(
                CodeSymbols.AltList,
                value.Parameters.EagerSelect(state.EncodeDefinition));

            var baseMethodNodes = state.Factory.Call(
                CodeSymbols.AltList,
                value.BaseMethods.EagerSelect(state.Encode));

            var argNodes = new List <LNode>()
            {
                state.Encode(value.Name),
                state.Encode(value.IsStatic),
                typeParamsNode,
                state.EncodeDefinition(value.ReturnParameter),
                parameterNodes,
                baseMethodNodes
            };

            if (value is IBodyMethod)
            {
                var body = ((IBodyMethod)value).Body;
                if (body != null)
                {
                    argNodes.Add(state.Encode(body.Implementation));
                }
            }

            return(state.Factory.Call(
                       value.IsConstructor ? CodeSymbols.Constructor : CodeSymbols.Fn,
                       argNodes)
                   .WithAttrs(
                       new VList <LNode>(
                           state.Encode(value.Attributes))));
        }
Пример #9
0
        /// <inheritdoc/>
        public override LNode Encode(IType value, EncoderState state)
        {
            if (value is PointerType)
            {
                var pointerType = (PointerType)value;
                var elemNode    = state.Encode(pointerType.ElementType);
                var kindNode    = EncodePointerKind(pointerType.Kind, state);
                return(state.Factory.Call(pointerSymbol, elemNode, kindNode));
            }
            else if (value is DirectTypeSpecialization)
            {
                var genericType = (DirectTypeSpecialization)value;
                var argNodes    = new IType[] { genericType.Declaration }
                .Concat <IType>(genericType.GenericArguments)
                .Select <IType, LNode>(state.Encode);

                return(state.Factory.Call(CodeSymbols.Of, argNodes));
            }
            else if (value is IGenericParameter)
            {
                return(state.Factory.Call(
                           genericParameterSymbol,
                           state.Encode(((IGenericParameter)value).ParentMember),
                           state.Encode(value.Name)));
            }

            var parent = value.Parent;

            if (parent.IsType)
            {
                var parentNode = state.Encode(parent.Type);
                var nameNode   = state.Encode(value.Name);
                return(state.Factory.Call(CodeSymbols.Dot, parentNode, nameNode));
            }
            else
            {
                return(state.Encode(value.FullName));
            }
        }
Пример #10
0
        /// <summary>
        /// Encodes a type definition as an LNode.
        /// </summary>
        /// <param name="value">The type definition to encode.</param>
        /// <param name="state">The encoder state.</param>
        /// <returns>An LNode that represents the type definition.</returns>
        public static LNode Encode(IType value, EncoderState state)
        {
            var nameNode = state.Encode(
                value.Parent.IsType || value.Parent.IsMethod
                ? value.Name.Qualify()
                : value.FullName);

            var typeParamsNode = state.Factory.Call(
                CodeSymbols.AltList,
                value.GenericParameters
                .Select(state.EncodeDefinition)
                .ToList());

            var baseTypesNode = state.Factory.Call(
                CodeSymbols.AltList,
                value.BaseTypes.EagerSelect(state.Encode));

            var membersNode = state.Factory.Call(
                CodeSymbols.Braces,
                value.NestedTypes
                .Select(state.EncodeDefinition)
                .Concat(value.Fields.Select(state.EncodeDefinition))
                .Concat(value.Methods.Select(state.EncodeDefinition))
                .Concat(value.Properties.Select(state.EncodeDefinition))
                .ToArray());

            return(state.Factory.Call(
                       value is IGenericParameter
                    ? TypeParameterDefinitionSymbol
                    : TypeDefinitionSymbol,
                       nameNode,
                       typeParamsNode,
                       baseTypesNode,
                       membersNode)
                   .WithAttrs(
                       new VList <LNode>(
                           state.Encode(value.Attributes))));
        }
Пример #11
0
 private static IReadOnlyList <LNode> EncodeStore(StorePrototype value, EncoderState state)
 {
     if (!value.Alignment.IsNaturallyAligned)
     {
         return(new LNode[]
         {
             state.Encode(value.ResultType),
             state.Encode(value.IsVolatile),
             state.Encode(value.Alignment)
         });
     }
     else if (value.IsVolatile)
     {
         return(new LNode[]
         {
             state.Encode(value.ResultType),
             state.Encode(value.IsVolatile)
         });
     }
     else
     {
         return(new LNode[] { state.Encode(value.ResultType) });
     }
 }
Пример #12
0
 private static IReadOnlyList <LNode> EncodeConstrainedCall(ConstrainedCallPrototype value, EncoderState state)
 {
     return(new LNode[]
     {
         state.Encode(value.Callee)
     });
 }
Пример #13
0
 private static IReadOnlyList <LNode> EncodeNewObject(NewObjectPrototype value, EncoderState state)
 {
     return(new LNode[]
     {
         state.Encode(value.Constructor)
     });
 }
Пример #14
0
 private static IReadOnlyList <LNode> EncodeReinterpretCast(ReinterpretCastPrototype value, EncoderState state)
 {
     return(new LNode[] { state.Encode(value.TargetType) });
 }
Пример #15
0
 private static IReadOnlyList <LNode> EncodeAllocaArray(AllocaArrayPrototype value, EncoderState state)
 {
     return(new LNode[] { state.Encode(value.ResultType) });
 }
Пример #16
0
 private static IReadOnlyList <LNode> EncodeNewDelegate(NewDelegatePrototype value, EncoderState state)
 {
     return(new LNode[]
     {
         state.Encode(value.ResultType),
         state.Encode(value.Callee),
         state.Encode(value.HasThisArgument),
         state.Encode(value.Lookup)
     });
 }
Пример #17
0
        private static IReadOnlyList <LNode> EncodeIndirectCall(IndirectCallPrototype value, EncoderState state)
        {
            var paramTypeNodes = new List <LNode>();

            foreach (var paramType in value.ParameterTypes)
            {
                paramTypeNodes.Add(state.Encode(paramType));
            }

            return(new LNode[]
            {
                state.Encode(value.ResultType),
                state.Factory.List(paramTypeNodes)
            });
        }
Пример #18
0
        private static IReadOnlyList <LNode> EncodeIntrinsic(IntrinsicPrototype value, EncoderState state)
        {
            // TODO: encode exception specifications.

            var paramTypeNodes = new List <LNode>();

            foreach (var paramType in value.ParameterTypes)
            {
                paramTypeNodes.Add(state.Encode(paramType));
            }

            return(new LNode[]
            {
                state.Factory.Id(value.Name),
                state.Encode(value.ResultType),
                state.Factory.List(paramTypeNodes)
            });
        }
Пример #19
0
 /// <inheritdoc/>
 public override LNode Encode(IType value, EncoderState state)
 {
     return(IrType.Encode(value, state));
 }
Пример #20
0
 private static IReadOnlyList <LNode> EncodeGetStaticFieldPointer(GetStaticFieldPointerPrototype value, EncoderState state)
 {
     return(new LNode[] { state.Encode(value.Field) });
 }
Пример #21
0
 /// <summary>
 /// Encodes a value.
 /// </summary>
 /// <param name="value">The value to encode.</param>
 /// <param name="state">The state of the encoder.</param>
 /// <returns>The encoded value.</returns>
 public abstract TEnc Encode(TObj value, EncoderState state);
Пример #22
0
        /// <summary>
        /// Encodes a constant value.
        /// </summary>
        /// <param name="value">The value to encode.</param>
        /// <param name="state">The encoder state to use.</param>
        /// <returns>An encoded constant value.</returns>
        public override LNode Encode(Constant value, EncoderState state)
        {
            if (value is NullConstant)
            {
                return(state.Factory.Null);
            }
            else if (value is DefaultConstant)
            {
                return(state.Factory.Id(CodeSymbols.Default));
            }
            else if (value is StringConstant)
            {
                return(state.Factory.Literal(((StringConstant)value).Value));
            }
            else if (value is IntegerConstant)
            {
                var integerConst = (IntegerConstant)value;

                // Try to encode integer types supported natively by
                // Loyc as integer literals instead of custom literals.
                if (integerConst.Spec.Equals(IntegerSpec.UInt1))
                {
                    return(state.Factory.Literal(((IntegerConstant)value).Value != 0));
                }
                else if (integerConst.Spec.Equals(IntegerSpec.UInt32))
                {
                    return(state.Factory.Literal(integerConst.ToUInt32()));
                }
                else if (integerConst.Spec.Equals(IntegerSpec.UInt64))
                {
                    return(state.Factory.Literal(integerConst.ToUInt64()));
                }
                else if (integerConst.Spec.Equals(IntegerSpec.Int32))
                {
                    return(state.Factory.Literal(integerConst.ToInt32()));
                }
                else if (integerConst.Spec.Equals(IntegerSpec.Int64))
                {
                    return(state.Factory.Literal(integerConst.ToInt64()));
                }
                else
                {
                    // Encode other integer constants as custom literals.
                    return(state.Factory.Literal(
                               new CustomLiteral(
                                   integerConst.Value.ToString(),
                                   GSymbol.Get(integerConst.Spec.ToString()))));
                }
            }
            else if (value is Float32Constant)
            {
                return(state.Factory.Literal(((Float32Constant)value).Value));
            }
            else if (value is Float64Constant)
            {
                return(state.Factory.Literal(((Float64Constant)value).Value));
            }
            else if (value is TypeTokenConstant)
            {
                return(state.Factory.Call(CodeSymbols.Typeof, state.Encode(((TypeTokenConstant)value).Type)));
            }
            else if (value is FieldTokenConstant)
            {
                return(state.Factory.Call(fieldofSymbol, state.Encode(((FieldTokenConstant)value).Field)));
            }
            else if (value is MethodTokenConstant)
            {
                return(state.Factory.Call(methodofSymbol, state.Encode(((MethodTokenConstant)value).Method)));
            }

            throw new NotSupportedException(
                      "Cannot encode unknown kind of literal '" + value.ToString() + "'.");
        }
Пример #23
0
 private static IReadOnlyList <LNode> EncodeBox(BoxPrototype value, EncoderState state)
 {
     return(new LNode[] { state.Encode(value.ElementType) });
 }
Пример #24
0
 private static IReadOnlyList <LNode> EncodeStoreField(StoreFieldPrototype value, EncoderState state)
 {
     return(new LNode[] { state.Encode(value.Field) });
 }
Пример #25
0
 private LNode EncodePointerKind(PointerKind kind, EncoderState state)
 {
     return(state.Factory.Id(pointerKindEncoding[kind]));
 }
Пример #26
0
 private static IReadOnlyList <LNode> EncodeSizeOf(SizeOfPrototype value, EncoderState state)
 {
     return(new LNode[] { state.Encode(value.MeasuredType), state.Encode(value.ResultType) });
 }
 private static IReadOnlyList <LNode> EncodeStore(StorePrototype value, EncoderState state)
 {
     return(new LNode[] { state.Encode(value.ResultType) });
 }
Пример #28
0
 private static IReadOnlyList <LNode> EncodeConstant(ConstantPrototype value, EncoderState state)
 {
     return(new LNode[] { state.Encode(value.Value), state.Encode(value.ResultType) });
 }
Пример #29
0
        /// <inheritdoc/>
        public override LNode Encode(ITypeMember value, EncoderState state)
        {
            if (value is IAccessor)
            {
                var acc = (IAccessor)value;

                return(state.Factory.Call(
                           accessorSymbol,
                           state.Encode(acc.ParentProperty),
                           state.Factory.Id(accessorKindEncodings[acc.Kind])));
            }
            else if (value is IField)
            {
                return(EncodeTypeAndName(value, state));
            }
            else if (value is IProperty)
            {
                var property = (IProperty)value;

                return(state.Factory.Call(
                           CodeSymbols.IndexBracks,
                           new[]
                {
                    EncodeTypeAndName(property, state)
                }.Concat(
                               property.IndexerParameters.EagerSelect(
                                   p => state.Encode(p.Type)))));
            }
            else if (value is DirectMethodSpecialization)
            {
                var spec = (DirectMethodSpecialization)value;

                return(state.Factory.Call(
                           CodeSymbols.Of,
                           new[]
                {
                    state.Encode(spec.Declaration)
                }.Concat(
                               spec.GenericArguments.EagerSelect(state.Encode))));
            }
            else if (value is IMethod)
            {
                var method = (IMethod)value;

                // Update the type codec so it can encode generic parameter
                // references.
                var innerState = method.GenericParameters.Count > 0
                    ? state.WithCodec(
                    state.Codec.WithTypes(
                        new GenericMethodTypeEncoder(
                            state.Codec.Types,
                            method.GenericParameters)))
                    : state;

                return(state.Factory.Call(
                           CodeSymbols.Lambda,
                           state.Factory.Call(
                               EncodeTypeAndName(method, state),
                               method.Parameters.EagerSelect(
                                   p => innerState.Encode(p.Type))),
                           innerState.Encode(method.ReturnParameter.Type)));
            }
            else
            {
                throw new NotSupportedException(
                          "Unknown kind of type member '" + value + "'.");
            }
        }