Пример #1
0
        static RedwoodType()
        {
            specialMappedTypes.Add("?", null);

            specialMappedTypes.Add("int", GetForCSharpType(typeof(int)));
            specialMappedTypes.Add("string", GetForCSharpType(typeof(string)));
            specialMappedTypes.Add("double", GetForCSharpType(typeof(double)));
            specialMappedTypes.Add("bool", GetForCSharpType(typeof(bool)));
            specialMappedTypes.Add("object", GetForCSharpType(typeof(object)));

            NullType.staticSlotMap = new Dictionary <string, int>();
            NullType.staticSlotMap[RuntimeUtil.NameForOperator(BinaryOperator.Equals)]    = 0;
            NullType.staticSlotMap[RuntimeUtil.NameForOperator(BinaryOperator.NotEquals)] = 1;
            NullType.staticSlotTypes = new RedwoodType[]
            {
                RedwoodType.GetForLambdaArgsTypes(
                    typeof(InPlaceLambda),
                    RedwoodType.GetForCSharpType(typeof(bool)),
                    new RedwoodType[] { null, null }
                    ),
                RedwoodType.GetForLambdaArgsTypes(
                    typeof(InPlaceLambda),
                    RedwoodType.GetForCSharpType(typeof(bool)),
                    new RedwoodType[] { null, null }
                    )
            };

            NullType.staticLambdas = new Lambda[] {
                new InPlaceLambda(
                    new RedwoodType[] { null, null },
                    GetForCSharpType(typeof(bool)),
                    new InPlaceLambdaExecutor((stack, locs) => {
                    return(stack[locs[0]] == null && stack[locs[1]] == null);
                })
                    ),
                new InPlaceLambda(
                    new RedwoodType[] { null, null },
                    GetForCSharpType(typeof(bool)),
                    new InPlaceLambdaExecutor((stack, locs) => {
                    return(stack[locs[0]] != null || stack[locs[1]] != null);
                })
                    )
            };
        }
Пример #2
0
        /// <summary>
        /// For the most part, the MemberResolver is able to resolve the
        /// methods, fields, and properties on C# types, but populating the
        /// slots for an interface will allow us to map to a specific order
        /// needed by the interface stitching done by the Emitter.
        /// </summary>
        private void InitInterfaceIfNecessary()
        {
            if (CSharpType == null || !CSharpType.IsInterface)
            {
                return;
            }

            IsInterface = true;

            var overloads = new Dictionary <string, Tuple <List <RedwoodType[]>, List <int> > >();
            int slot      = 0;
            List <RedwoodType> slotTypes = new List <RedwoodType>();

            slotMap      = new Dictionary <string, int>();
            overloadsMap = new Dictionary <int, Tuple <RedwoodType[][], int[]> >();

            foreach (MethodInfo method in CSharpType.GetMethods())
            {
                RedwoodType[] parameterTypes = method
                                               .GetParameters()
                                               .Select(param => RedwoodType.GetForCSharpType(param.ParameterType))
                                               .ToArray();
                if (!overloads.ContainsKey(method.Name))
                {
                    overloads[method.Name] = new Tuple <List <RedwoodType[]>, List <int> >(
                        new List <RedwoodType[]>(),
                        new List <int>()
                        );
                }

                slotTypes.Add(RedwoodType.GetForLambdaArgsTypes(
                                  typeof(ExternalLambda),
                                  RedwoodType.GetForCSharpType(method.ReturnType),
                                  parameterTypes
                                  ));

                overloads[method.Name].Item1.Add(parameterTypes);
                overloads[method.Name].Item2.Add(slot);
                slot++;
            }

            // For interfaces, the methods are all at the beginnings, overloads
            // all at the end
            foreach (string overloadName in overloads.Keys)
            {
                // TODO: Do we care about the overload type here?
                int[] overloadSlots = overloads[overloadName].Item2.ToArray();
                slotTypes.Add(RedwoodType
                              .GetForCSharpType(typeof(LambdaGroup))
                              .GetGenericSpecialization(
                                  overloadSlots
                                  .Select(slot => slotTypes[slot])
                                  .ToArray()
                                  )
                              );;


                slotMap[overloadName] = slot;
                overloadsMap[slot]    = new Tuple <RedwoodType[][], int[]>(
                    overloads[overloadName].Item1.ToArray(),
                    overloadSlots
                    );
                slot++;
            }

            numSlots       = slot;
            this.slotTypes = slotTypes.ToArray();
            // Technically a proxy type can occur from any redwood type to
            // any C# interface, but we emit for the interface we created
            // and then reuse it so that we can keep a cceiling on the
            // number of these classes that we create
            proxyType = Emitter.EmitInterfaceProxyType(this, CSharpType);
            ConstructorInfo constructor = proxyType.GetConstructor(new Type[] { typeof(object[]) });

            Constructor = new ExternalLambda(this, constructor);
        }