private ILGen MakeRawKeysMethod()
        {
            FieldBuilder rawKeysCache = TypeGen.AddStaticField(typeof(SymbolId[]), "ExtraKeysCache");
            ILGen        init         = TypeGen.TypeInitializer;

            init.EmitInt(_fields.Count);
            init.Emit(OpCodes.Newarr, typeof(SymbolId));

            int current = 0;

            foreach (GlobalVariableExpression variable in _fields.Keys)
            {
                init.Emit(OpCodes.Dup);
                init.EmitInt(current++);
                EmitSymbolId(init, SymbolTable.StringToId(variable.Name));
                init.EmitStoreElement(typeof(SymbolId));
            }

            init.Emit(OpCodes.Stsfld, rawKeysCache);

            MethodInfo baseMethod = typeof(CustomSymbolDictionary).GetMethod("GetExtraKeys", BindingFlags.Public | BindingFlags.Instance);
            ILGen      cg         = TypeGen.DefineExplicitInterfaceImplementation(baseMethod);

            cg.Emit(OpCodes.Ldsfld, rawKeysCache);
            cg.Emit(OpCodes.Ret);
            return(cg);
        }
        // This generates a method like the following:
        //
        //  TrySetExtraValue(object name, object value) {
        //      if (name1 == name) {
        //          type.name1Slot = value;
        //          return 1;
        //      }
        //      if (name2 == name) {
        //          type.name2Slot = value;
        //          return 1;
        //      }
        //      ...
        //      return 0
        //  }

        private void MakeSetMethod()
        {
            MethodInfo baseMethod = typeof(CustomSymbolDictionary).GetMethod("TrySetExtraValue", BindingFlags.NonPublic | BindingFlags.Instance);
            ILGen      cg         = TypeGen.DefineMethodOverride(baseMethod);

            foreach (KeyValuePair <GlobalVariableExpression, FieldBuilder> kv in _fields)
            {
                SymbolId name = SymbolTable.StringToId(kv.Key.Name);

                EmitSymbolId(cg, name);
                // arg0 -> this
                cg.EmitLoadArg(1);
                cg.EmitCall(typeof(SymbolId), "op_Equality");

                Label next = cg.DefineLabel();
                cg.Emit(OpCodes.Brfalse_S, next);

                cg.EmitFieldGet(kv.Value);
                cg.EmitLoadArg(2);
                cg.EmitPropertySet(typeof(ModuleGlobalWrapper), "CurrentValue");

                cg.EmitInt(1);
                cg.Emit(OpCodes.Ret);
                cg.MarkLabel(next);
            }
            cg.EmitInt(0);
            cg.Emit(OpCodes.Ret);
        }
예제 #3
0
        protected override KeyValuePair<MethodBuilder, Type> CompileForSave(TypeGen typeGen) {
            var lambda = RewriteForSave(typeGen, _code);

            MethodBuilder mb = typeGen.TypeBuilder.DefineMethod(lambda.Name ?? "lambda_method", CompilerHelpers.PublicStatic | MethodAttributes.SpecialName);
            lambda.CompileToMethod(mb, false);
            return new KeyValuePair<MethodBuilder, Type>(mb, typeof(DlrMainCallTarget));
        }
        private void MakeInitialization()
        {
            TypeGen.TypeBuilder.AddInterfaceImplementation(typeof(IModuleDictionaryInitialization));
            MethodInfo baseMethod = typeof(IModuleDictionaryInitialization).GetMethod("InitializeModuleDictionary");
            ILGen      cg         = TypeGen.DefineExplicitInterfaceImplementation(baseMethod);

            Label ok = cg.DefineLabel();

            cg.EmitFieldGet(_contextField);
            cg.Emit(OpCodes.Ldnull);
            cg.Emit(OpCodes.Ceq);
            cg.Emit(OpCodes.Brtrue_S, ok);
            cg.EmitNew(typeof(InvalidOperationException), Type.EmptyTypes);
            cg.Emit(OpCodes.Throw);
            cg.MarkLabel(ok);

            // arg0 -> this
            // arg1 -> MyModuleDictType.ContextSlot
            cg.EmitLoadArg(1);
            cg.EmitFieldSet(_contextField);

            ConstructorInfo wrapperCtor = typeof(ModuleGlobalWrapper).GetConstructor(new Type[] { typeof(CodeContext), typeof(SymbolId) });

            foreach (KeyValuePair <GlobalVariableExpression, FieldBuilder> kv in _fields)
            {
                // wrapper = new ModuleGlobalWrapper(context, name);
                cg.EmitLoadArg(1);
                EmitSymbolId(cg, SymbolTable.StringToId(kv.Key.Name));
                cg.Emit(OpCodes.Newobj, wrapperCtor);
                cg.Emit(OpCodes.Stsfld, kv.Value);
            }

            cg.Emit(OpCodes.Ret);
        }
예제 #5
0
        public CodeGen DefineMethod(string methodName, Type returnType, IList <Type> paramTypes, ConstantPool constantPool)
        {
            CodeGen cg;

            if (GenerateStaticMethods)
            {
                int     index = Interlocked.Increment(ref _index);
                TypeGen tg    = DefinePublicType("Type$" + methodName + "$" + index, typeof(object));
                cg = tg.DefineMethod("Handle" + index, returnType, paramTypes, null, constantPool);
                cg.DynamicMethod = true;
            }
            else
            {
                Type[]        parameterTypes    = CompilerHelpers.MakeParamTypeArray(paramTypes, constantPool);
                string        dynamicMethodName = methodName + "##" + Interlocked.Increment(ref _index);
                DynamicMethod target;
#if SILVERLIGHT // Module-hosted DynamicMethod is not available in SILVERLIGHT
                target = new DynamicMethod(dynamicMethodName, returnType, parameterTypes);
#else
                target = new DynamicMethod(dynamicMethodName, returnType, parameterTypes, _myModule);
#endif
                cg = new CodeGen(null, this, target, target.GetILGenerator(), parameterTypes, constantPool);
            }
            return(cg);
        }
        protected override Expression VisitConstant(ConstantExpression node)
        {
            object data = node.Value;
            Type   type = node.Type;

            // if the constant can be emitted into IL, nothing to do
            if (CanEmitConstant(data, type))
            {
                return(node);
            }

            type = TypeUtils.GetConstantType(type);

            int index;

            if (!_constantCache.TryGetValue(data, out index))
            {
                int          number = AddStaticData(data);
                FieldBuilder field  = TypeGen.AddStaticField(type, "#Constant" + number);
                index = _staticFields.Count;
                _staticFields.Add(field);
                _constantCache.Add(data, index);
            }

            return(Expression.Field(null, _staticFields[index]));
        }
예제 #7
0
        protected override KeyValuePair<MethodBuilder, Type> CompileForSave(TypeGen typeGen, Dictionary<SymbolId, FieldBuilder> symbolDict) {
            var lambda = RewriteForSave(typeGen, _code);

            lambda = Expression.Lambda<Func<Scope, LanguageContext, object>>(
                Expression.Block(
                    new[] { IronPython.Compiler.Ast.ArrayGlobalAllocator._globalContext },
                    Expression.Assign(
                        IronPython.Compiler.Ast.ArrayGlobalAllocator._globalContext,
                        Expression.Call(
                            null,
                            typeof(PythonOps).GetMethod("CreateTopLevelCodeContext"),
                            lambda.Parameters[0],
                            lambda.Parameters[1]
                        )
                    ),
                    lambda.Body
                ),
                lambda.Name,
                lambda.Parameters
            );

            MethodBuilder mb = typeGen.TypeBuilder.DefineMethod(lambda.Name ?? "lambda_method", CompilerHelpers.PublicStatic | MethodAttributes.SpecialName);
            lambda.CompileToMethod(mb, false);

            mb.SetCustomAttribute(new CustomAttributeBuilder(
                typeof(CachedOptimizedCodeAttribute).GetConstructor(new Type[] { typeof(string[]) }),
                new object[] { _names }
            ));

            return new KeyValuePair<MethodBuilder, Type>(mb, typeof(Func<Scope, LanguageContext, object>));
        }
        //
        // This generates a method like the following:
        //
        //  TryGetExtraValue(int name, object out value) {
        //      if (name1 == name) {
        //          value = type.name1Slot.RawValue;
        //          return value != Uninitialized.Instance;
        //      }
        //      if (name2 == name) {
        //          value = type.name2Slot.RawValue;
        //          return value != Uninitialized.Instance;
        //      }
        //      ...
        //      return false
        //  }

        private void MakeGetMethod()
        {
            MethodInfo baseMethod = typeof(CustomSymbolDictionary).GetMethod("TryGetExtraValue", BindingFlags.NonPublic | BindingFlags.Instance);
            ILGen      cg         = TypeGen.DefineMethodOverride(baseMethod);

            foreach (KeyValuePair <GlobalVariableExpression, FieldBuilder> kv in _fields)
            {
                SymbolId name = SymbolTable.StringToId(kv.Key.Name);

                EmitSymbolId(cg, name);
                // arg0 -> this
                cg.EmitLoadArg(1);
                cg.EmitCall(typeof(SymbolId), "op_Equality");

                Label next = cg.DefineLabel();
                cg.Emit(OpCodes.Brfalse_S, next);

                cg.EmitLoadArg(2);

                // Expects to push as an object.
                EmitGetRawFromObject(cg, kv.Value);
                cg.Emit(OpCodes.Stind_Ref);

                EmitGetRawFromObject(cg, kv.Value);
                cg.EmitFieldGet(typeof(Uninitialized), "Instance");
                cg.Emit(OpCodes.Ceq);
                cg.Emit(OpCodes.Not);
                cg.Emit(OpCodes.Ret);
                cg.MarkLabel(next);
            }
            cg.EmitInt(0);
            cg.Emit(OpCodes.Ret);
        }
예제 #9
0
        public StaticGlobalAllocator(LanguageContext/*!*/ context, string name) {
            _typeGen = Snippets.Shared.DefineType(name, typeof(object), false, false);

            _codeContextField = _typeGen.AddStaticField(typeof(CodeContext), "__global_context");
            _codeContext = CreateFieldBuilderExpression(_codeContextField);

            _scope = new Scope(new PythonDictionary(new GlobalDictionaryStorage(_globalVals)));
            _context = new CodeContext(_scope, context);
        }
예제 #10
0
        private TypeGen GenerateModuleGlobalsType(AssemblyGen ag)
        {
            TypeGen tg = ag.DefinePublicType(ModuleName == "ironscheme.boot.new" ? "#" : ModuleName, typeof(CustomSymbolDictionary));

            tg.AddCodeContextField();
            tg.DefaultConstructor = tg.TypeBuilder.DefineDefaultConstructor(MethodAttributes.Public);

            return(tg);
        }
예제 #11
0
        public TypeGen DefineDebuggableType(string typeName, SourceUnit sourceUnit)
        {
            typeName = typeName.Replace(Type.Delimiter, '_'); // '.' is for separating the namespace and the type name.
            DebugAssembly.SetSourceUnit(sourceUnit);
            TypeGen tg = DebugAssembly.DefinePublicType(typeName + "$" + _debugTypeIndex++, typeof(object));

            tg.TypeBuilder.DefineDefaultConstructor(MethodAttributes.Public);
            return(tg);
        }
예제 #12
0
        internal static CodeGen CreateDebuggableDynamicCodeGenerator(CompilerContext context, string name, Type retType, IList <Type> paramTypes, IList <string> paramNames, ConstantPool constantPool)
        {
            TypeGen tg = ScriptDomainManager.CurrentManager.Snippets.DefineDebuggableType(name, context.SourceUnit);
            CodeGen cg = tg.DefineMethod("Initialize", retType, paramTypes, paramNames, constantPool);

            tg.AddCodeContextField();
            cg.DynamicMethod = true;

            return(cg);
        }
예제 #13
0
        protected override KeyValuePair<MethodBuilder, Type> CompileForSave(TypeGen typeGen) {
            var lambda = RewriteForSave(typeGen, _code);

            MethodBuilder mb = typeGen.TypeBuilder.DefineMethod(lambda.Name ?? "lambda_method", CompilerHelpers.PublicStatic | MethodAttributes.SpecialName);
            lambda.CompileToMethod(mb, false);

            mb.SetCustomAttribute(new CustomAttributeBuilder(
                typeof(CachedOptimizedCodeAttribute).GetConstructor(new Type[] { typeof(string[]) }),
                new object[] { _names }
            ));

            return new KeyValuePair<MethodBuilder, Type>(mb, typeof(LookupCompilationDelegate));
        }
예제 #14
0
        public TypeGen DefineNestedType(string name, Type parent)
        {
            TypeBuilder tb = _myType.DefineNestedType(name, TypeAttributes.NestedPublic);

            tb.SetParent(parent);
            TypeGen ret = new TypeGen(_myAssembly, tb);

            _nestedTypeGens.Add(ret);

            ret.AddCodeContextField();

            return(ret);
        }
예제 #15
0
        protected override Expression VisitExtension(Expression node)
        {
            if (node.NodeType == ExpressionType.Dynamic)
            {
                // the node was dynamic, the dynamic nodes were removed,
                // we now need to rewrite any call sites.
                return(VisitDynamic((DynamicExpression)node));
            }

            SymbolConstantExpression symbol = node as SymbolConstantExpression;

            if (symbol != null)
            {
                SymbolId id = symbol.Value;

                if (id == SymbolId.Empty)
                {
                    return(Expression.Field(null, typeof(SymbolId).GetField("Empty")));
                }

                FieldBuilderExpression value;
                if (!_indirectSymbolIds.TryGetValue(id, out value))
                {
                    // create field, emit fix-up...

                    if (_symbolGen == null)
                    {
                        _symbolGen = new TypeGen(_typeGen.AssemblyGen, ((ModuleBuilder)_typeGen.TypeBuilder.Module).DefineType("Symbols" + Interlocked.Increment(ref _id)));
#if SILVERLIGHT
                        _finishedSymbolType = new StrongBox <Type>();
#endif
                    }
                    FieldBuilder field = _symbolGen.AddStaticField(typeof(SymbolId), FieldAttributes.Public, SymbolTable.IdToString(id));
                    ILGen        init  = _symbolGen.TypeInitializer;
                    if (_indirectSymbolIds.Count == 0)
                    {
                        init.EmitType(_symbolGen.TypeBuilder);
                        init.EmitCall(typeof(ScriptingRuntimeHelpers), "InitializeSymbols");
                    }
#if SILVERLIGHT
                    _indirectSymbolIds[id] = value = new FieldBuilderExpression(field, _finishedSymbolType);
#else
                    _indirectSymbolIds[id] = value = new FieldBuilderExpression(field);
#endif
                }
                Debug.Assert(value != null);
                return(value);
            }
            return(Visit(node.Reduce()));
        }
예제 #16
0
        private TypeGen GenerateModuleGlobalsType(AssemblyGen ag, ScriptCode sc)
        {
            var n = sc.CodeBlock.Name;

            switch (n)
            {
            case "visit-code":
            case "invoke-code":
            case "guard-code":
                TypeGen tg = ag.DefinePublicType("syntax-" + sc.CodeBlock.Name, typeof(CustomSymbolDictionary));
                tg.AddCodeContextField();
                tg.DefaultConstructor = tg.TypeBuilder.DefineDefaultConstructor(MethodAttributes.Public);
                return(tg);

            default:
                return(GenerateModuleGlobalsType(ag));
            }
        }
예제 #17
0
        protected override SlotFactory CreateSlotFactory(ScriptCode scriptCode)
        {
            AssemblyGen ag = null;

            if (scriptCode.SourceUnit.Kind == SourceCodeKind.Default && scriptCode.CodeBlock.Name != "ironscheme.boot.new")
            {
                if (ScriptDomainManager.Options.DebugMode)
                {
                    if ((ScriptDomainManager.Options.AssemblyGenAttributes & AssemblyGenAttributes.SaveAndReloadAssemblies) != 0)
                    {
                        ag = ScriptDomainManager.CurrentManager.Snippets.CurrentAssembly;
                        //CreateModuleAssembly(scriptCode);
                    }
                    else
                    {
                        ag = ScriptDomainManager.CurrentManager.Snippets.DebugAssembly;
                    }
                }
                else
                {
                    if ((ScriptDomainManager.Options.AssemblyGenAttributes & AssemblyGenAttributes.SaveAndReloadAssemblies) != 0)
                    {
                        ag = ScriptDomainManager.CurrentManager.Snippets.CurrentAssembly;
                        //CreateModuleAssembly(scriptCode);
                    }
                    else
                    {
                        ag = ScriptDomainManager.CurrentManager.Snippets.Assembly;
                    }
                }
            }
            else
            {
                ag = ScriptDomainManager.CurrentManager.Snippets.CurrentAssembly; //CreateModuleAssembly(scriptCode);
            }

            ScriptDomainManager.CurrentManager.Snippets.CurrentAssembly = ag;

            TypeGen tg = GenerateModuleGlobalsType(ag, scriptCode);

            if (scriptCode.LibraryGlobals != null)
            {
                foreach (var kvp in scriptCode.LibraryGlobals)
                {
                    var k = kvp.Key;
                    var v = kvp.Value;

                    var cg = v.Block.CreateGlobalMethodStub(tg);

                    if (cg != null)
                    {
                        CodeGen._codeBlockStubs[v.Block] = cg;
                        CodeGen._codeBlockLookup[k]      = cg;
                    }
                }
            }

            if (scriptCode.LibraryGlobalsX != null)
            {
                foreach (var kvp in scriptCode.LibraryGlobalsX)
                {
                    var k = kvp.Key;
                    var v = kvp.Value;

                    var cg = v.Block.CreateGlobalMethodStub(tg);

                    if (cg != null)
                    {
                        CodeGen._codeBlockStubsX[v.Block] = cg;
                        CodeGen._codeBlockLookupX[k]      = cg;
                    }
                }
            }

            if (scriptCode.LibraryGlobalsN != null)
            {
                foreach (var kvp in scriptCode.LibraryGlobalsN)
                {
                    var k = kvp.Key;
                    var v = kvp.Value;

                    var cgd = new List <CodeGenDescriptor>();

                    foreach (var i in v)
                    {
                        var cg = i.codeblock.Block.CreateGlobalMethodStub(tg);

                        if (cg != null)
                        {
                            CodeGen._codeBlockStubsN[i.codeblock.Block] = cg;

                            cgd.Add(new CodeGenDescriptor
                            {
                                arity   = i.arity,
                                varargs = i.varargs,
                                cg      = cg,
                            });
                        }
                    }

                    CodeGen._codeBlockLookupN[k] = cgd.ToArray();
                }
            }

            StaticFieldSlotFactory factory = new StaticFieldSlotFactory(tg);

            _languages[scriptCode.LanguageContext] = new LanguageInfo(factory, tg);

            return(factory);
        }
예제 #18
0
 public LanguageInfo(StaticFieldSlotFactory slotFactory, TypeGen tg)
 {
     TypeGen     = tg;
     SlotFactory = slotFactory;
 }
예제 #19
0
 internal GlobalArrayRewriter(Dictionary <SymbolId, FieldBuilder> symbolDict, TypeGen typeGen)
     : base(symbolDict)
 {
     TypeGen = typeGen;
 }
예제 #20
0
        private static void EmitOverrideGetHashCode(TypeGen typeGen) {
            Type baseType = typeGen.TypeBuilder.BaseType;
            MethodInfo baseMethod = baseType.GetMethod("GetHashCode", Type.EmptyTypes);
            Compiler cg = typeGen.DefineMethodOverride(baseMethod);

            // Check if a "hash" method exists on this class
            cg.EmitType(typeGen.TypeBuilder);
            cg.EmitString("hash");
            cg.EmitCall(typeof(RubyOps).GetMethod("ResolveDeclaredInstanceMethod"));
            Label callBase = cg.DefineLabel();
            cg.Emit(OpCodes.Brfalse_S, callBase);

            // If so, call it
            cg.EmitThis();
            cg.EmitCall(typeof(RubyOps).GetMethod("CallHash"));
            cg.EmitReturn();

            // Otherwise, call base class
            cg.MarkLabel(callBase);
            cg.EmitThis();
            cg.Emit(OpCodes.Call, baseMethod); // base call must be non-virtual
            cg.EmitReturn();

            cg.Finish();
        }
예제 #21
0
 public StaticFieldSlotFactory(TypeGen typeGen)
 {
     _typeGen = typeGen;
 }
예제 #22
0
 internal ToDiskRewriter(TypeGen typeGen)
 {
     _typeGen = typeGen;
 }
예제 #23
0
        /// <summary>
        /// This takes an assembly name including extension and saves the provided ScriptCode objects into the assembly.  
        /// 
        /// The provided script codes can constitute code from multiple languages.  The assemblyName can be either a fully qualified 
        /// or a relative path.  The DLR will simply save the assembly to the desired location.  The assembly is created by the DLR and 
        /// if a file already exists than an exception is raised.  
        /// 
        /// The DLR determines the internal format of the ScriptCode and the DLR can feel free to rev this as appropriate.  
        /// </summary>
        public static void SaveToAssembly(string assemblyName, params SavableScriptCode[] codes) {
            ContractUtils.RequiresNotNull(assemblyName, "assemblyName");
            ContractUtils.RequiresNotNullItems(codes, "codes");

            // break the assemblyName into it's dir/name/extension
            string dir = Path.GetDirectoryName(assemblyName);
            if (String.IsNullOrEmpty(dir)) {
                dir = Environment.CurrentDirectory;
            }

            string name = Path.GetFileNameWithoutExtension(assemblyName);
            string ext = Path.GetExtension(assemblyName);

            // build the assembly & type gen that all the script codes will live in...
            AssemblyGen ag = new AssemblyGen(new AssemblyName(name), dir, ext, /*emitSymbols*/false);
            TypeBuilder tb = ag.DefinePublicType("DLRCachedCode", typeof(object), true);
            TypeGen tg = new TypeGen(ag, tb);
            var symbolDict = new Dictionary<SymbolId, FieldBuilder>();
            // then compile all of the code

            Dictionary<Type, List<CodeInfo>> langCtxBuilders = new Dictionary<Type, List<CodeInfo>>();
            foreach (SavableScriptCode sc in codes) {
                List<CodeInfo> builders;
                if (!langCtxBuilders.TryGetValue(sc.LanguageContext.GetType(), out builders)) {
                    langCtxBuilders[sc.LanguageContext.GetType()] = builders = new List<CodeInfo>();
                }

                KeyValuePair<MethodBuilder, Type> compInfo = sc.CompileForSave(tg, symbolDict);

                builders.Add(new CodeInfo(compInfo.Key, sc, compInfo.Value));
            }

            MethodBuilder mb = tb.DefineMethod(
                "GetScriptCodeInfo",
                MethodAttributes.SpecialName | MethodAttributes.Public | MethodAttributes.Static,
                typeof(MutableTuple<Type[], Delegate[][], string[][], string[][]>),
                Type.EmptyTypes);

            ILGen ilgen = new ILGen(mb.GetILGenerator());

            var langsWithBuilders = langCtxBuilders.ToArray();

            // lang ctx array
            ilgen.EmitArray(typeof(Type), langsWithBuilders.Length, (index) => {
                ilgen.Emit(OpCodes.Ldtoken, langsWithBuilders[index].Key);
                ilgen.EmitCall(typeof(Type).GetMethod("GetTypeFromHandle", new[] { typeof(RuntimeTypeHandle) }));
            });

            // builders array of array
            ilgen.EmitArray(typeof(Delegate[]), langsWithBuilders.Length, (index) => {
                List<CodeInfo> builders = langsWithBuilders[index].Value;

                ilgen.EmitArray(typeof(Delegate), builders.Count, (innerIndex) => {
                    ilgen.EmitNull();
                    ilgen.Emit(OpCodes.Ldftn, builders[innerIndex].Builder);
                    ilgen.EmitNew(
                        builders[innerIndex].DelegateType,
                        new[] { typeof(object), typeof(IntPtr) }
                    );
                });
            });

            // paths array of array
            ilgen.EmitArray(typeof(string[]), langsWithBuilders.Length, (index) => {
                List<CodeInfo> builders = langsWithBuilders[index].Value;

                ilgen.EmitArray(typeof(string), builders.Count, (innerIndex) => {
                    ilgen.EmitString(builders[innerIndex].Code.SourceUnit.Path);
                });
            });

            // 4th element in tuple - custom per-language data
            ilgen.EmitArray(typeof(string[]), langsWithBuilders.Length, (index) => {
                List<CodeInfo> builders = langsWithBuilders[index].Value;

                ilgen.EmitArray(typeof(string), builders.Count, (innerIndex) => {
                    ICustomScriptCodeData data = builders[innerIndex].Code as ICustomScriptCodeData;
                    if (data != null) {
                        ilgen.EmitString(data.GetCustomScriptCodeData());
                    } else {
                        ilgen.Emit(OpCodes.Ldnull);
                    }
                });
            });

            ilgen.EmitNew(
                typeof(MutableTuple<Type[], Delegate[][], string[][], string[][]>),
                new[] { typeof(Type[]), typeof(Delegate[][]), typeof(string[][]), typeof(string[][]) }
            );
            ilgen.Emit(OpCodes.Ret);

            mb.SetCustomAttribute(new CustomAttributeBuilder(
                typeof(DlrCachedCodeAttribute).GetConstructor(Type.EmptyTypes),
                ArrayUtils.EmptyObjects
            ));

            tg.FinishType();
            ag.SaveAssembly();
        }
예제 #24
0
 protected LambdaExpression RewriteForSave(TypeGen typeGen, LambdaExpression code) {
     var diskRewriter = new ToDiskRewriter(typeGen);
     return diskRewriter.RewriteLambda(code);
 }
예제 #25
0
 public FieldSlotFactory(TypeGen typeGen, Slot instance)
 {
     this._typeGen  = typeGen;
     this._instance = instance;
 }
예제 #26
0
    static void GenerateConstructor(RecordTypeDescriptor rtd, TypeGen tg, Type parenttype)
    {
      // constructor logic
      {
        List<Type> paramtypes = new List<Type>();
        List<FieldDescriptor> allfields = new List<FieldDescriptor>(rtd.GetAllFields());

        int diff = allfields.Count - rtd.Fields.Length;

        foreach (FieldDescriptor var in allfields)
        {
          paramtypes.Add(var.Type);
        }

        List<Type> parenttypes = new List<Type>();

        for (int i = 0; i < diff; i++)
        {
          parenttypes.Add(typeof(object)); //TODO: fix this, it looks broken
        }

        if (paramtypes.Count < 9)
        {
          CodeGen cg = tg.DefineConstructor(paramtypes.ToArray());

          CodeGen mk = tg.DefineMethod(MethodAttributes.Public | MethodAttributes.Static, "make",
           tg.TypeBuilder, paramtypes.ToArray(), allfields.ConvertAll(x => x.Name).ToArray());


          for (int i = 0; i < allfields.Count; i++)
          {
            cg.DefineParameter(i + 1, ParameterAttributes.None, allfields[i].Name);
          }

          int fi = 0;

          cg.EmitThis();


          for (fi = 0; fi < diff; fi++)
          {
            cg.EmitArgGet(fi);
            mk.EmitArgGet(fi);
          }

          cg.Emit(OpCodes.Call, (rtd.Parent == null ? parenttype.GetConstructor(Type.EmptyTypes) : rtd.Parent.DefaultConstructor));

          foreach (FieldDescriptor fd in rtd.Fields)
          {
            cg.EmitThis();
            cg.EmitArgGet(fi);
            cg.EmitFieldSet(fd.field);

            mk.EmitArgGet(fi);

            fi++;
          }

          mk.EmitNew(cg.MethodBase as ConstructorInfo);
          mk.EmitReturn();

          cg.EmitReturn();

          rtd.cg = cg;
        }
        else
        {

          CodeGen cg = tg.DefineConstructor(paramtypes.ToArray());
          CodeGen mk = tg.DefineMethod(MethodAttributes.Public | MethodAttributes.Static, "make",
           tg.TypeBuilder, new Type[] { typeof(object[]) }, new string[] { "args" });


          for (int i = 0; i < allfields.Count; i++)
          {
            cg.DefineParameter(i + 1, ParameterAttributes.None, allfields[i].Name);
          }

          int fi = 0;

          cg.EmitThis();


          for (fi = 0; fi < diff; fi++)
          {
            cg.EmitArgGet(fi);

            mk.EmitArgGet(0);
            mk.EmitConstant(fi);
            mk.Emit(OpCodes.Ldelem, typeof(object));
          }

          cg.Emit(OpCodes.Call, (rtd.Parent == null ? typeof(object).GetConstructor(Type.EmptyTypes) : rtd.Parent.DefaultConstructor));

          foreach (FieldDescriptor fd in rtd.Fields)
          {
            cg.EmitThis();
            cg.EmitArgGet(fi);
            cg.EmitFieldSet(fd.field);

            mk.EmitArgGet(0);
            mk.EmitConstant(fi);
            mk.Emit(OpCodes.Ldelem, typeof(object));

            fi++;
          }

          mk.EmitNew(cg.MethodBase as ConstructorInfo);
          mk.EmitReturn();

          cg.EmitReturn();

          rtd.cg = cg;
        }
      }
    }
예제 #27
0
        internal static Type/*!*/ GetDelegateType(TypeGen/*!*/ typeGen, Type/*!*/ retType, System.Linq.Expressions.Expression/*!*/[]/*!*/ args) {
            Type delegateType;
            if (retType != typeof(void)) {
                Type[] types = new Type[args.Length + 2];
                types[0] = typeof(CallSite);

                for (int i = 0; i < args.Length; i++) {
                    types[i + 1] = args[i].Type;
                }

                types[types.Length - 1] = retType;
                delegateType = GetFuncType(types) ?? MakeNewCustomDelegate(typeGen, types);
            } else {
                Type[] types = new Type[args.Length + 2];
                types[0] = typeof(CallSite);

                for (int i = 0; i < args.Length; i++) {
                    types[i + 1] = args[i].Type;
                }
                delegateType = GetActionType(types) ?? MakeNewCustomDelegate(typeGen, ArrayUtils.Append(types, typeof(void)));
            }
            return delegateType;
        }
예제 #28
0
        protected virtual MethodBuilder CompileForSave(TypeGen typeGen, Dictionary<SymbolId, FieldBuilder> symbolDict) {
            var diskRewriter = new ToDiskRewriter(typeGen);
            var lambda = diskRewriter.RewriteLambda(_code);

            MethodBuilder mb = typeGen.TypeBuilder.DefineMethod(lambda.Name ?? "lambda_method", CompilerHelpers.PublicStatic | MethodAttributes.SpecialName);
            lambda.CompileToMethod(mb, false);
            return mb;
        }
예제 #29
0
        internal MethodBuilder CompileToDisk(TypeGen typeGen, Dictionary<SymbolId, FieldBuilder> symbolDict) {
            if (_code == null) {
                throw Error.NoCodeToCompile();
            }

            MethodBuilder mb = CompileForSave(typeGen, symbolDict);
            return mb;
        }
예제 #30
0
 protected virtual KeyValuePair<MethodBuilder, Type> CompileForSave(TypeGen typeGen) {
     throw new NotSupportedException();
 }
예제 #31
0
        public TypeGen DefineNestedType(string name, Type parent) {
            TypeBuilder tb = _myType.DefineNestedType(name, TypeAttributes.NestedPublic);
            tb.SetParent(parent);
            TypeGen ret = new TypeGen(_myAssembly, tb);
            _nestedTypeGens.Add(ret);

            ret.AddCodeContextField();

            return ret;
        }
예제 #32
0
    static void GeneratePredicate(string n, RecordTypeDescriptor rtd, TypeGen tg)
    {
      // predicate

      MethodBuilder pb = tg.TypeBuilder.DefineMethod(n + "?", MethodAttributes.Public | MethodAttributes.Static,
        typeof(object), new Type[] { typeof(object) });

      pb.DefineParameter(1, ParameterAttributes.None, "obj");

      ILGenerator pgen = pb.GetILGenerator();
      pgen.Emit(OpCodes.Ldarg_0);
      pgen.Emit(OpCodes.Isinst, tg.TypeBuilder);
      pgen.Emit(OpCodes.Ldnull);
      pgen.Emit(OpCodes.Cgt_Un);
      pgen.Emit(OpCodes.Call, typeof(RuntimeHelpers).GetMethod("BooleanToObject"));
      pgen.Emit(OpCodes.Ret);

      rtd.predicate = pb;
    }
예제 #33
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();
    }
예제 #34
0
 protected virtual KeyValuePair<MethodBuilder, Type> CompileForSave(TypeGen typeGen, Dictionary<SymbolId, FieldBuilder> symbolDict) {
     throw new NotSupportedException();
 }
 public LanguageInfo(StaticFieldSlotFactory slotFactory, TypeGen tg)
 {
     TypeGen = tg;
     SlotFactory = slotFactory;
 }
예제 #36
0
 public FieldSlotFactory(TypeGen typeGen, Slot instance)
 {
     this._typeGen = typeGen;
     this._instance = instance;
 }
예제 #37
0
        // we need to get the right execution context
#if OBSOLETE
        private static void EmitOverrideEquals(TypeGen typeGen) {
            Type baseType = typeGen.TypeBuilder.BaseType;
            MethodInfo baseMethod = baseType.GetMethod("Equals", new Type[] { typeof(object) });
            Compiler cg = typeGen.DefineMethodOverride(baseMethod);

            // Check if an "eql?" method exists on this class
            cg.EmitType(typeGen.TypeBuilder);
            cg.EmitString("eql?");
            cg.EmitCall(typeof(RubyOps).GetMethod("ResolveDeclaredInstanceMethod"));
            Label callBase = cg.DefineLabel();
            cg.Emit(OpCodes.Brfalse_S, callBase);

            // If so, call it
            cg.EmitThis();
            cg.EmitArgGet(0);
            cg.EmitCall(typeof(RubyOps).GetMethod("CallEql"));
            cg.EmitReturn();

            // Otherwise, call base class
            cg.MarkLabel(callBase);
            cg.EmitThis();
            cg.EmitArgGet(0);
            cg.Emit(OpCodes.Call, baseMethod); // base call must be non-virtual
            cg.EmitReturn();

            cg.Finish();
        }
 internal GlobalStaticFieldRewriter(TypeGen typeGen)
 {
     TypeGen = typeGen;
 }
예제 #39
0
 public StaticFieldSlotFactory(TypeGen typeGen)
 {
     _typeGen = typeGen;
 }
예제 #40
0
        private static Type/*!*/ MakeNewCustomDelegate(TypeGen/*!*/ typeGen, Type/*!*/[]/*!*/ types) {
            Type returnType = types[types.Length - 1];
            Type[] parameters = ArrayUtils.RemoveLast(types);

            TypeBuilder builder = Snippets.Shared.DefineDelegateType("Delegate" + types.Length);
            builder.DefineConstructor(CtorAttributes, CallingConventions.Standard, _DelegateCtorSignature).SetImplementationFlags(ImplAttributes);
            builder.DefineMethod("Invoke", InvokeAttributes, returnType, parameters).SetImplementationFlags(ImplAttributes);
            return builder.CreateType();
        }
예제 #41
0
 private void MaybeInit()
 {
     if (_typeBuilder == null)
     {
         _typeBuilder = _assemblyGen.DefinePublicType(_typeName, typeof(object), true);
         _typeGen = new TypeGen(_assemblyGen, _typeBuilder);
         _fieldBuilders = new List<FieldBuilder>();
         _fieldInits = new List<Expression>();
     }
 }
예제 #42
0
        protected override KeyValuePair<MethodBuilder, Type> CompileForSave(TypeGen typeGen, Dictionary<SymbolId, FieldBuilder> symbolDict) {
            // first, serialize constants and dynamic sites:
            ToDiskRewriter diskRewriter = new ToDiskRewriter(typeGen);
            LambdaExpression lambda = diskRewriter.RewriteLambda(Code);
            
            // rewrite global variables:
            var globalRewriter = new GlobalArrayRewriter(symbolDict, typeGen);
            lambda = globalRewriter.RewriteLambda(lambda);
            
            MethodBuilder builder = typeGen.TypeBuilder.DefineMethod(lambda.Name ?? "lambda_method", CompilerHelpers.PublicStatic | MethodAttributes.SpecialName);
            lambda.CompileToMethod(builder, false);

            builder.SetCustomAttribute(new CustomAttributeBuilder(
                typeof(CachedOptimizedCodeAttribute).GetConstructor(new Type[] { typeof(string[]) }),
                new object[] { ArrayUtils.ToArray(globalRewriter.Names) }
            ));

            return new KeyValuePair<MethodBuilder, Type>(builder, typeof(DlrMainCallTarget));
        }
예제 #43
0
        private Expression RewriteCallSite(CallSite site, TypeGen tg)
        {
            IExpressionSerializable serializer = site.Binder as IExpressionSerializable;
            if (serializer == null)
            {
                throw new ArgumentException("Generating code from non-serializable CallSiteBinder.");
            }

            Type siteType = site.GetType();

            FieldBuilder fb = tg.AddStaticField(siteType, "sf" + (_id++).ToString());
            Expression init = Expression.Call(siteType.GetMethod("Create"), serializer.CreateExpression());

            _fieldBuilders.Add(fb);
            _fieldInits.Add(init);

            Type t = init.Type;
            if (t.IsGenericType)
            {
                Type[] args = t.GetGenericArguments()[0].GetGenericArguments(); ;
                // skip the first one, it is the site.
                for (int k = 1; k < args.Length; k++)
                {
                    Type p = args[k];
                    //if (!p.Assembly.GetName().Name.Equals("mscorlib") && !p.Assembly.GetName().Name.Equals("Clojure"))
                    //    Console.WriteLine("Found {0}", p.ToString());
                }
            }

            // rewrite the node...
            return Expression.Field(null, fb);
        }