private static void MakeSlotsDeleteTarget(MemberBindingInfo/*!*/ info, ReflectedSlotProperty/*!*/ rsp) {
     MakeSlotsSetTarget(info, rsp, Ast.Field(null, typeof(Uninitialized).GetField("Instance")));
 }
        private static void MakeSlotsSetTarget(MemberBindingInfo/*!*/ info, ReflectedSlotProperty/*!*/ rsp, Expression/*!*/ value) {
            // type has __slots__ defined for this member, call the setter directly
            ParameterExpression tmp = Ast.Variable(typeof(object), "res");
            info.Body.AddVariable(tmp);

            info.Body.FinishCondition(
                Ast.Block(
                    Ast.Assign(
                        tmp,
                        Ast.Convert(
                            Ast.Assign(
                                Ast.ArrayAccess(
                                    Ast.Call(
                                        Ast.Convert(info.Args[0].Expression, typeof(IObjectWithSlots)),
                                        typeof(IObjectWithSlots).GetMethod("GetSlots")
                                    ),
                                    Ast.Constant(rsp.Index)
                                ),
                                AstUtils.Convert(value, typeof(object))
                            ),
                            tmp.Type
                        )
                    ),
                    tmp
                )
            );
        }
        public static Type GetNewType(string typeName, Tuple bases, IDictionary<object, object> dict)
        {
            // we're really only interested in the "correct" base type pulled out of bases
            // and any slot information contained in dict
            // other info might be used for future optimizations

            Debug.Assert(bases != null);
            NewTypeInfo typeInfo = GetTypeInfo(typeName, bases, GetSlots(dict));

            if (typeInfo.BaseType.IsSealed || typeInfo.BaseType.IsValueType)
                throw Ops.TypeError("cannot derive from sealed or value types");

            Type ret = newTypes.GetOrCreateValue(typeInfo,
                delegate() {
                    // creation code
                    return GetTypeMaker(bases, typeName, typeInfo).CreateNewType();
                });

            if (typeInfo.Slots != null) {
                // update dict w/ slots that point at the correct fields.

                for (int i = 0; i < typeInfo.Slots.Count; i++) {
                    PropertyInfo pi = ret.GetProperty(typeInfo.Slots[i]);
                    string name = typeInfo.Slots[i];
                    if (name.StartsWith("__") && !name.EndsWith("__")) {
                        name = "_" + typeName + name;
                    }
                    dict[name] = new ReflectedSlotProperty(pi, pi.GetGetMethod(), pi.GetSetMethod(), NameType.PythonProperty);
                }
            }

            return ret;
        }