Example #1
0
        /// <summary>
        /// Determines whether the specified type is an <see cref="ExtensibleEnum{T}"/> type.
        /// </summary>
        /// <param name="type">The type to be checked.</param>
        /// <returns>
        ///   <see langword="true"/> if the specified type is an extensible enum type; otherwise, <see langword="false"/>.
        /// </returns>
        /// <exception cref="ArgumentNullException">The <paramref name="type"/> parameter is <see langword="null" />.</exception>
        /// <remarks>
        /// For performance reasons, this method only checks if the <paramref name="type"/> implements <see cref="IExtensibleEnum"/>, it does not
        /// check whether the type is derived from <see cref="ExtensibleEnum{T}"/>. The <see cref="GetDefinition"/> method, however, will throw
        /// an exception when used with a type not derived from <see cref="ExtensibleEnum{T}"/>.
        /// </remarks>
        public static bool IsExtensibleEnumType(ITypeInformation type)
        {
            ArgumentUtility.CheckNotNull("type", type);

            return(s_extensibleEnumInterfaceType.IsAssignableFrom(type) &&
                   !type.Equals(s_extensibleEnumGenericBaseType) &&
                   !(type.IsGenericType && type.GetGenericTypeDefinition().Equals(s_extensibleEnumGenericBaseType)) &&
                   !type.Equals(s_extensibleEnumInterfaceType));
        }
Example #2
0
        public override Func <IExtractContext, string[]> Apply(
            ITypeInformation operand, DecodeContext decodeContext)
        {
            var si = decodeContext.PopStack();

            if (!(si.TargetType.IsValueType &&                                                       // We have to value type
                  (operand.Equals(si.TargetType) ||                                                  // Same type
                   (operand.IsInt32StackFriendlyType && si.TargetType.IsInt32StackFriendlyType) ||   // Same size or implicit expanders
                   (operand.IsInt64StackFriendlyType && si.TargetType.IsInt64StackFriendlyType) ||   // Same size
                   (operand.IsIntPtrStackFriendlyType && si.TargetType.IsIntPtrStackFriendlyType)))) // Same size
            {
                throw new InvalidProgramSequenceException(
                          "Invalid type at stack: Location={0}, TokenType={1}, StackType={2}",
                          decodeContext.CurrentCode.RawLocation,
                          operand.FriendlyName,
                          si.TargetType.FriendlyName);
            }

            // NOTE: The 'O' type means System.Object, but we have to push the System.ValueType (BoxedValueTypeInformation).
            //   Because the boxed value types can implicit cast to both types.
            //   The upcast can be inlining (System.ValueType --> System.Object),
            //   but downcast requires runtime cast operator (System.Object --> System.ValueType).
            var symbol = decodeContext.PushStack(
                new BoxedValueTypeInformation(si.TargetType));

            // NOTE: The IL2C strict type infers the evaluation stack.
            //   The unbox operator is handling by the pointer.
            //   So, we have to simulate implicitly conversion from little size value to large size value.
            //   (It's only 8/16 --> 32bit. See ECMA-335 III.1.1.1 Numeric data types)
            //   We can use conversion with the "il2c_box2" function in this case.
            //   For example:
            //     // object value = (byte)123;
            //     ldc.i4.s 123                 // int32_t
            //     box [mscorlib]System.Byte    // int32_t --> objref(uint8_t)   // size[4] --> size[1]
            if (operand.InternalStaticSizeOfValue == si.TargetType.InternalStaticSizeOfValue)
            {
                return(extractContext =>
                {
                    return new[] { string.Format(
                                       "{0} = il2c_box(&{1}, {2})",
                                       extractContext.GetSymbolName(symbol),
                                       extractContext.GetSymbolName(si),
                                       operand.MangledName) };
                });
            }
            else
            {
                return(extractContext =>
                {
                    return new[] { string.Format(
                                       "{0} = il2c_box2(&{1}, {2}, {3})",
                                       extractContext.GetSymbolName(symbol),
                                       extractContext.GetSymbolName(si),
                                       operand.MangledName,
                                       si.TargetType.MangledName) };
                });
            }
        }
Example #3
0
 public bool IsAssignableFrom(ITypeInformation rhs)
 {
     return(rhs.Equals(boxedType));
 }