Exemple #1
0
        static Type GetGenericType(string typename, Type[] types)
        {
            int l        = types.Length;
            var functype = ClrGenerator.GetTypeFast(typename + "`" + l).MakeGenericType(types);

            return(functype);
        }
Exemple #2
0
        public static object GetClrType(object name, params object[] typeargs)
        {
            SymbolId s = RequiresNotNull <SymbolId>(name);

            string tn = SymbolTable.IdToString(s);

            var t = ClrGenerator.GetTypeFast(tn);

            if (t == null)
            {
                return(FALSE);
            }

            if (typeargs.Length == 0)
            {
                return(t);
            }

            return(t.MakeGenericType(Array.ConvertAll(typeargs, x => (Type)x)));
        }
Exemple #3
0
        static void GenerateFields(object fields, string n, RecordTypeDescriptor rtd, TypeGen tg, object fieldtypes)
        {
            object[] f      = RequiresNotNull <object[]>(fields);
            object[] ftypes = RequiresNotNull <object[]>(fieldtypes);

            List <FieldDescriptor> rtd_fields = new List <FieldDescriptor>();

            for (int i = 0; i < f.Length; i++)
            {
                Cons c = (Cons)f[i];
                Type t = ClrGenerator.ExtractTypeInfo(List(SymbolTable.StringToObject("quote"), ftypes[i]));

                if (t == null)
                {
                    ClrGenerator.ClrSyntaxError("GenerateFields", "type not found", ftypes[i]);
                }

                string fname = SymbolTable.IdToString(RequiresNotNull <SymbolId>(Second(c)));
                // we use standard names here, they will be mapped to the given names
                string aname = n + "-" + fname;
                string mname = n + "-" + fname + "-set!";

                var fd = new FieldDescriptor {
                    Name = fname
                };

                FieldAttributes fattrs = FieldAttributes.Public | FieldAttributes.InitOnly;
                if (c.car == SymbolTable.StringToObject("mutable"))
                {
                    fd.mutable = true;
                    fattrs    &= ~FieldAttributes.InitOnly;
                }
                FieldSlot s = tg.AddField(t, fname, fattrs) as FieldSlot;

                fd.field = s.Field;

                PropertyBuilder pi = tg.TypeBuilder.DefineProperty(fname, PropertyAttributes.None, t, new Type[0]);

                // accesor

                MethodBuilder ab = tg.TypeBuilder.DefineMethod(aname, MethodAttributes.Public | MethodAttributes.Static,
                                                               t, new Type[] { tg.TypeBuilder });

                ab.DefineParameter(1, ParameterAttributes.None, n);

                ILGenerator agen = ab.GetILGenerator();
                agen.Emit(OpCodes.Ldarg_0);
                //agen.Emit(OpCodes.Castclass, tg.TypeBuilder);
                agen.Emit(OpCodes.Ldfld, fd.field);
                agen.Emit(OpCodes.Ret);

                fd.accessor = ab;
                pi.SetGetMethod(ab);

                // mutator
                if (fd.mutable)
                {
                    MethodBuilder mb = tg.TypeBuilder.DefineMethod(mname, MethodAttributes.Public | MethodAttributes.Static,
                                                                   typeof(object), new Type[] { tg.TypeBuilder, t });

                    mb.DefineParameter(1, ParameterAttributes.None, n);

                    ILGenerator mgen = mb.GetILGenerator();
                    mgen.Emit(OpCodes.Ldarg_0);
                    //mgen.Emit(OpCodes.Castclass, tg.TypeBuilder);
                    mgen.Emit(OpCodes.Ldarg_1);
                    mgen.Emit(OpCodes.Stfld, fd.field);
                    mgen.Emit(OpCodes.Ldsfld, Compiler.Generator.Unspecified);
                    mgen.Emit(OpCodes.Ret);

                    fd.mutator = mb;
                    pi.SetSetMethod(mb);
                }

                rtd_fields.Add(fd);
            }

            rtd.fields = rtd_fields.ToArray();
        }
Exemple #4
0
        public static RecordTypeDescriptor GenerateRecordTypeDescriptor(AssemblyGen ag, object name, object parent, object uid, object issealed, object isopaque, object fields, object fieldtypes)
        {
            string n  = SymbolTable.IdToString(RequiresNotNull <SymbolId>(name));
            string id = uid is SymbolId?SymbolTable.IdToString(RequiresNotNull <SymbolId>(uid)) : uid as string;

            if (id != null)
            {
                RecordTypeDescriptor ngrtd;
                if (nongenerative.TryGetValue(n + id, out ngrtd))
                {
                    return(ngrtd);
                }

                var type = ClrGenerator.GetTypeFast("record." + id + "." + n.Replace("&", "$"));

                if (type != null)
                {
                    return(RecordTypeDescriptor.Create(type, n, id, parent as RecordTypeDescriptor));
                }
            }

            bool @sealed = RequiresNotNull <bool>(issealed);
            bool opaque  = RequiresNotNull <bool>(isopaque);

            RecordTypeDescriptor prtd = parent as RecordTypeDescriptor; // can be #f

            Type parenttype = typeof(object);

            if (prtd != null)
            {
                parenttype = prtd.type;
            }
            else if (n == "&condition")
            {
                parenttype = typeof(Condition);
            }

            TypeAttributes attrs = TypeAttributes.Public | TypeAttributes.Serializable;

            var rtd = new RecordTypeDescriptor
            {
                Name       = n,
                @sealed    = @sealed,
                opaque     = opaque,
                ag         = ag,
                Parent     = prtd,
                uid        = uid,
                generative = id == null || uid is string,
            };

            if (@sealed)
            {
                attrs |= TypeAttributes.Sealed;
            }

            object gid      = (object)id ?? Guid.NewGuid();
            var    ns       = "record." + gid;
            var    typename = ns + "." + n.Replace("&", "$");

            TypeGen tg = ag.DefinePublicType(typename, parenttype, attrs);

            rtd.tg   = tg;
            rtd.type = tg.TypeBuilder;

            if (id != null)
            {
                nongenerative[n + id] = rtd;
            }

            if (parenttype.IsSubclassOf(typeof(Condition)))
            {
                SetSymbolValueFast(SymbolTable.StringToObject(n + "-rtd"), rtd);
            }

            GeneratePredicate(n, rtd, tg);

            GenerateFields(fields, n, rtd, tg, fieldtypes);

            GenerateConstructor(rtd, tg, parenttype);

            return(rtd);
        }
Exemple #5
0
        public static Expression MakeRecordTypeDescriptor(Expression[] obj)
        {
            if ((obj.Length == 6 || obj.Length == 7) && IronScheme.Compiler.Generator.VarHint != SymbolId.Empty)
            {
                try
                {
                    var name     = Unwrap(obj[0]);
                    var parent   = Unwrap(obj[1]);
                    var uid      = Unwrap(obj[2]);
                    var issealed = Unwrap(obj[3]);
                    var isopaque = Unwrap(obj[4]);
                    var fields   = obj[5];
                    if (fields is BoundExpression)
                    {
                        return(null);
                    }

                    if (name is BoundExpression)
                    {
                        return(null);
                    }

                    var rname   = ((ConstantExpression)name).Value;
                    var ruid    = ((ConstantExpression)uid).Value;
                    var rsealed = ((ConstantExpression)issealed).Value;
                    var ropaque = ((ConstantExpression)isopaque).Value;

                    object[] rfields = { };

                    if (fields is NewArrayExpression)
                    {
                        var ff      = ((NewArrayExpression)fields).Expressions;
                        var dfields = new Expression[ff.Count];
                        ff.CopyTo(dfields, 0);

                        rfields = Array.ConvertAll(dfields, x => ((ConstantExpression)x).Value);
                    }

                    object[] tfields = Array.ConvertAll(rfields, x => SymbolTable.StringToObject("Object"));

                    if (obj.Length == 7)
                    {
                        var ftypes = obj[6];

                        if (ftypes is NewArrayExpression)
                        {
                            var ff      = ((NewArrayExpression)ftypes).Expressions;
                            var dfields = new Expression[ff.Count];
                            ff.CopyTo(dfields, 0);

                            tfields = Array.ConvertAll(dfields, x => ((ConstantExpression)((UnaryExpression)x).Operand).Value);
                        }
                    }

                    if (!Builtins.IsTrue(ruid))
                    {
                        ruid   = Guid.NewGuid().ToString(); //TODO: recall why this was done :\ Change to gensym if possible
                        obj[2] = Ast.Convert(Ast.Constant(ruid), typeof(object));
                    }

                    object par = null;

                    if (parent is BoundExpression)
                    {
                        par = ((BoundExpression)parent).Variable.Name;
                    }

                    var rtdc = new RecordTypeDescriptorConstant
                    {
                        RecordName = rname,
                        Uid        = ruid,
                        Sealed     = rsealed,
                        Opaque     = ropaque,
                        Parent     = par,
                        Fields     = rfields,
                        FieldTypes = tfields,
                        NameHint   = IronScheme.Compiler.Generator.VarHint,
                    };

                    var at = rtdc.Generate();

                    if (at != null)
                    {
                        ClrGenerator.AddCompileTimeType(at);
                    }

                    var e = Ast.Constant(rtdc);

                    return(Ast.Comma(e, Ast.Call(typeof(Records).GetMethod("MakeRecordTypeDescriptor"), obj)));
                }
                catch
                {
                    throw;
                    //kaboom, redirect to runtime
                }
            }

            return(null);
        }