private FieldInfo GetSymbolField(SymbolId id) { Debug.Assert(TypeGen != null); if (id == SymbolId.Empty) { return(typeof(SymbolId).GetField("Empty")); } FieldBuilder value; if (!_indirectSymbolIds.TryGetValue(id, out value)) { // create field, emit fix-up... value = TypeGen.AddStaticField(typeof(SymbolId), FieldAttributes.Public, SymbolTable.IdToString(id)); ILGen init = TypeGen.TypeInitializer; if (_indirectSymbolIds.Count == 0) { init.EmitType(TypeGen.TypeBuilder); init.EmitCall(typeof(ScriptingRuntimeHelpers), "InitializeSymbols"); } _indirectSymbolIds[id] = value; } return(value); }
private static void EmitExplicitCast(ILGen il, Type from, Type to) { if (!il.TryEmitExplicitCast(from, to)) { throw new ArgumentException(String.Format("Cannot cast from '{0}' to '{1}'", from, to)); } }
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); }
// // 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); }
void CreateStaticCtor() { //Console.WriteLine("Creating static ctor for {0}", // _typeBuilder.AssemblyQualifiedName); ConstructorBuilder ctorB = _typeBuilder.DefineConstructor(MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes); ILGen gen = new ILGen(ctorB.GetILGenerator()); for (int i = 0; i < _fieldBuilders.Count; i++) { FieldBuilder fb = _fieldBuilders[i]; Expression fbInit = _fieldInits[i]; string setterName = String.Format("{0}_setter", fb.Name); MethodBuilder mbSetter = _typeBuilder.DefineMethod( setterName, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, fbInit.Type, Type.EmptyTypes); LambdaExpression initL = Expression.Lambda(Expression.Assign(Expression.Field(null, fb), fbInit)); initL.CompileToMethod(mbSetter); gen.EmitCall(mbSetter); gen.Emit(OpCodes.Pop); } gen.Emit(OpCodes.Ret); }
// Returns true if the label was successfully defined // or false if the label is now ambiguous internal void Define(ILGen il, LabelBlockInfo block) { // Prevent the label from being shadowed, which enforces cleaner // trees. Also we depend on this for simplicity (keeping only one // active IL Label per LabelInfo) for (LabelBlockInfo j = block; j != null; j = j.Parent) { if (j.ContainsTarget(Node)) { throw Error.LabelTargetAlreadyDefined(Node.Name); } } Definitions.Add(block); block.AddLabelInfo(Node, this); // Once defined, validate all jumps if (Definitions.Count == 1) { foreach (var r in References) { ValidateJump(r); } } else { // Was just redefined, if we had any across block jumps, they're // now invalid if (_acrossBlockJump) { throw Error.AmbiguousJump(Node.Name); } // For local jumps, we need a new IL label // This is okay because: // 1. no across block jumps have been made or will be made // 2. we don't allow the label to be shadowed Label = il.DefineLabel(); } }
public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args) { if (args.Length != 2) throw new ArgumentException("Unproperly formated cast expression"); engine.CompileExpr(il, locals, st, args[0]); Type type = args[1] as Type; if (type == null) throw new ArgumentException("Expecting type value"); Type curr_type = st.Pop(); if (curr_type.IsValueType) { if (type == typeof(System.Object)) il.EmitBoxing(curr_type); else if (curr_type != type) throw new InvalidCastException(); } else { il.Emit(OpCodes.Isinst, type); il.Emit(OpCodes.Dup); Label ok = il.DefineLabel(); il.Emit(OpCodes.Brtrue_S, ok); il.EmitCall(_raiseInvalidCast); il.MarkLabel(ok); if (type.IsValueType) il.EmitUnbox(type); } st.Push(type); }
/// <summary> /// Loads all the incoming arguments and forwards them to mi which /// has the same signature and then returns the result /// </summary> private void EmitBaseMethodDispatch(MethodInfo mi, ILGen il) { if (!mi.IsAbstract) { int offset = 0; if (!mi.IsStatic) { il.EmitLoadArg(0); offset = 1; } ParameterInfo[] parameters = mi.GetParameters(); for (int i = 0; i < parameters.Length; i++) { il.EmitLoadArg(i + offset); } il.EmitCall(OpCodes.Call, mi, null); // base call must be non-virtual il.Emit(OpCodes.Ret); } else { il.EmitLoadArg(0); il.EmitString(mi.Name); il.EmitCall(MissingInvokeMethodException()); il.Emit(OpCodes.Throw); } }
public override Type Compile(Executive engine, ILGen il, LocalAccess locals, Type[] parameterTypes) { for (int k = 0; k < parameterTypes.Length; k++) il.Emit(OpCodes.Pop); il.EmitFieldGet(typeof(DBNull), "Value"); return typeof(DBNull); }
internal static Type Create(GenContext context, Type baseClass) { //ModuleBuilder mb = context.ModuleBldr; string name = baseClass.Name + "_impl"; //TypeBuilder baseTB = context.ModuleBldr.DefineType(name, TypeAttributes.Class | TypeAttributes.Public, baseClass); TypeBuilder baseTB = context.AssemblyGen.DefinePublicType(name, baseClass, true); ObjExpr.MarkAsSerializable(baseTB); baseTB.DefineDefaultConstructor(MethodAttributes.Public); FieldBuilder metaField = baseTB.DefineField("_meta", typeof(IPersistentMap), FieldAttributes.Public); MethodBuilder metaMB = baseTB.DefineMethod("meta", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.ReuseSlot, typeof(IPersistentMap), Type.EmptyTypes); ILGen gen = new ILGen(metaMB.GetILGenerator()); gen.EmitLoadArg(0); gen.EmitFieldGet(metaField); gen.Emit(OpCodes.Ret); MethodBuilder withMB = baseTB.DefineMethod("withMeta", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.ReuseSlot, typeof(IObj), new Type[] { typeof(IPersistentMap)}); gen = new ILGen(withMB.GetILGenerator()); gen.EmitLoadArg(0); gen.EmitCall(Compiler.Method_Object_MemberwiseClone); gen.Emit(OpCodes.Castclass, baseTB); gen.Emit(OpCodes.Dup); gen.EmitLoadArg(1); gen.EmitFieldSet(metaField); gen.Emit(OpCodes.Ret); for (int i = 0; i < 20; i++ ) DefineDelegateFieldAndOverride(baseTB, i); return baseTB.CreateType(); }
private void DefineDynamicObjectImplementation() { _tb.AddInterfaceImplementation(typeof(IDynamicObject)); // MetaObject! IDynamicObject.GetMetaObject(Expression! parameter) { // return RubyOps.GetMetaObject(this, parameter); // } MethodInfo decl = typeof(IDynamicObject).GetMethod("GetMetaObject"); MethodBuilder impl = _tb.DefineMethod( decl.Name, decl.Attributes & ~(MethodAttributes.Abstract | MethodAttributes.ReservedMask), decl.ReturnType, ReflectionUtils.GetParameterTypes(decl.GetParameters()) ); ILGen il = new ILGen(impl.GetILGenerator()); il.EmitLoadArg(0); il.EmitLoadArg(1); il.EmitCall(Methods.GetMetaObject); il.Emit(OpCodes.Ret); _tb.DefineMethodOverride(impl, decl); }
public void FixReturn(ILGen /*!*/ il) { il.EmitLoadArg(_index); il.Emit(OpCodes.Ldloc, _reference); il.EmitFieldGet(_reference.LocalType.GetField("Value")); il.EmitStoreValueIndirect(_parameter.ParameterType.GetElementType()); }
internal void FixReturn(ILGen cg) { cg.EmitLoadArg(_argIndex); cg.Emit(OpCodes.Ldloc, _refSlot); cg.Emit(OpCodes.Ldfld, _refSlot.LocalType.GetDeclaredField("Value")); cg.EmitStoreValueIndirect(_argType.GetElementType()); }
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); }
protected ILGen GetCCtor() { if (_cctor == null) { ConstructorBuilder cctor = _tb.DefineTypeInitializer(); _cctor = CreateILGen(cctor.GetILGenerator()); } return _cctor; }
public static void EmitDebugInfo(ILGen ilg, IPersistentMap spanMap) { if (Compiler.CompilerContextVar.deref() is GenContext context) { context.MaybeEmitDebugInfo(ilg, spanMap); } }
static void EmitMain(GenContext context, TypeBuilder proxyTB, string mainName, FieldBuilder mainFB) { MethodBuilder cb = proxyTB.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(void), new Type[] { typeof(String[]) }); ILGen gen = new ILGen(cb.GetILGenerator());; Label noMainLabel = gen.DefineLabel(); Label endLabel = gen.DefineLabel(); EmitGetVar(gen, mainFB); gen.Emit(OpCodes.Dup); gen.Emit(OpCodes.Brfalse_S, noMainLabel); gen.Emit(OpCodes.Castclass, typeof(IFn)); gen.EmitLoadArg(0); // gen.Emit(OpCodes.Ldarg_0); gen.EmitCall(Method_RT_seq); // gen.Emit(OpCodes.Call, Method_RT_seq); gen.EmitCall(Method_IFn_applyTo_Object_ISeq); // gen.Emit(OpCodes.Call, Method_IFn_applyTo_Object_ISeq); gen.Emit(OpCodes.Pop); gen.Emit(OpCodes.Br_S, endLabel); // no main found gen.MarkLabel(noMainLabel); EmitUnsupported(gen, mainName); gen.MarkLabel(endLabel); gen.Emit(OpCodes.Ret); //context.AssyBldr.SetEntryPoint(cb); context.AssemblyBuilder.SetEntryPoint(cb); }
private ConstructorBuilder GenerateFieldOnlyConstructor(TypeBuilder fnTB, Type baseType) { Type[] ctorTypes = CtorTypes(); Type[] altCtorTypes = new Type[ctorTypes.Length - _altCtorDrops]; for (int i = 0; i < altCtorTypes.Length; i++) { altCtorTypes[i] = ctorTypes[i]; } ConstructorBuilder cb = fnTB.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, altCtorTypes); ILGen gen = new ILGen(cb.GetILGenerator()); //Call full constructor gen.EmitLoadArg(0); // gen.Emit(OpCodes.Ldarg_0); for (int i = 0; i < altCtorTypes.Length; i++) { gen.EmitLoadArg(i + 1); } for (int i = 0; i < _altCtorDrops; i++) { gen.EmitNull(); } gen.Emit(OpCodes.Call, _ctorInfo); gen.Emit(OpCodes.Ret); return(cb); }
public static void EmitOp(MethodInfo method, ILGen ilg) { OpCode[] opcodes = _ops[method]; // special case the shift methods because we didn't create a way to embed arguments to the opcodes. // the long second-arg bit-shifts need to mask to a value <= 63 // the int second-arg bit-shifts need to maks to a value <= 31 switch (method.Name) { case "shiftLeft": case "shiftRight": case "unsignedShiftRight": ilg.Emit(OpCodes.Conv_I4); ilg.EmitInt(0x3f); ilg.Emit(OpCodes.And); break; case "shiftLeftInt": case "shiftRightInt": case "unsignedShiftRightInt": ilg.EmitInt(0x1f); ilg.Emit(OpCodes.And); break; } foreach (OpCode opcode in opcodes) { ilg.Emit(opcode); } }
public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args) { il.Emit(OpCodes.Ldarg_1); il.EmitInt(locals.DefineConstant(args[0])); il.Emit(OpCodes.Ldelem_Ref); st.Push(typeof(System.Object)); }
static void Main(string[] args) { Console.Title = "UBHackingCompiler"; if (args.Length != 2) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine(@"Please use '-dll [filename]' to compile"); Console.ReadLine(); } Tokenizer.Read(new StreamReader(args[1])); var filename = Path.GetFileNameWithoutExtension(args[1]); ILGen.moduleName = filename; var location = Path.GetFileNameWithoutExtension(args[1]); Parser.Start(); ILGen.GenHeader(); Parser.Create(); Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine(ILGen.ILCode); if (File.Exists(location + ".il")) { File.Delete(location + ".il"); } if (File.Exists(location + ".dll")) { File.Delete(location + ".dll"); } var sw = File.AppendText(location + ".il"); sw.Write(ILGen.ILCode); sw.Flush(); sw.Close(); Console.ForegroundColor = ConsoleColor.Green; }
protected override void EmitMakeCallAction(string name, int nargs, bool isList) { ILGen cctor = GetCCtor(); cctor.Emit(OpCodes.Ldstr, name); cctor.EmitInt(nargs); cctor.EmitCall(typeof(RubyCallAction), "Make", new Type[] { typeof(string), typeof(int) }); }
protected override void EmitMakeCallAction(string name, int nargs, bool isList) { ILGen cctor = GetCCtor(); cctor.Emit(OpCodes.Ldstr, name); cctor.EmitInt(nargs); cctor.EmitCall(typeof(RubyTypeEmitter), "MakeRubyCallSite"); }
/// <summary> /// Emit code to convert object to a given type. This code is semantically equivalent /// to PythonBinder.EmitConvertFromObject, except this version accepts ILGen whereas /// PythonBinder accepts Compiler. The Binder will chagne soon and the two will merge. /// </summary> public void EmitConvertFromObject(ILGen il, Type toType) { if (toType == typeof(object)) { return; } else if (toType == typeof(void)) { il.Emit(OpCodes.Pop); return; } var callTarget = il.DeclareLocal(typeof(object)); il.Emit(OpCodes.Stloc, callTarget); if (toType.IsGenericParameter && toType.DeclaringMethod != null) { MethodInfo siteFactory = GetGenericConversionSiteFactory(toType); Debug.Assert(siteFactory.GetParameters().Length == 0 && typeof(CallSite).IsAssignableFrom(siteFactory.ReturnType)); // siteVar = GetConversionSite<T>() var siteVar = il.DeclareLocal(siteFactory.ReturnType); il.Emit(OpCodes.Call, siteFactory); il.Emit(OpCodes.Stloc, siteVar); // Emit the site invoke il.Emit(OpCodes.Ldloc, siteVar); FieldInfo target = siteVar.LocalType.GetField("Target"); il.EmitFieldGet(target); il.Emit(OpCodes.Ldloc, siteVar); // Emit the context EmitContext(il, false); il.Emit(OpCodes.Ldloc, callTarget); il.EmitCall(target.FieldType, "Invoke"); } else { var site = GetConversionSiteField(toType); // Emit the site invoke il.EmitFieldGet(site); FieldInfo target = site.FieldType.GetField("Target"); il.EmitFieldGet(target); il.EmitFieldGet(site); // Emit the context EmitContext(il, false); il.Emit(OpCodes.Ldloc, callTarget); il.EmitCall(target.FieldType, "Invoke"); } }
public static void EmitOp(MethodInfo method, ILGen ilg) { OpCode[] opcodes = _ops[method]; foreach (OpCode opcode in opcodes) { ilg.Emit(opcode); } }
private MethodBuilder CreateVTableMethodOverride(MethodInfo mi, string name) { MethodBuilder impl; ILGen il = DefineMethodOverride(MethodAttributes.Public, mi, out impl); EmitVirtualSiteCall(il, mi, name); _tb.DefineMethodOverride(impl, mi); return(impl); }
protected ILGen GetCCtor() { if (_cctor == null) { ConstructorBuilder cctor = _tb.DefineTypeInitializer(); _cctor = CreateILGen(cctor.GetILGenerator()); } return(_cctor); }
public static void EmitPred(MethodInfo method, ILGen ilg, Label falseLabel) { OpCode[] opcodes = _preds[method]; for (int i = 0; i < opcodes.Length - 1; i++) { ilg.Emit(opcodes[i]); } ilg.Emit(opcodes[opcodes.Length - 1], falseLabel); }
private static void EmitConstantGet(ILGen il, int index, Type type) { il.Emit(OpCodes.Ldarg_0); il.EmitInt(index); il.Emit(OpCodes.Ldelem_Ref); if (type != typeof(object)) { il.Emit(OpCodes.Castclass, type); } }
public void Create(NameSpace name_space) { ILGen.AddLine(".class public auto ansi beforefieldinit"); ILGen.AddLine(name_space.name + "." + name); ILGen.AddLine("extends [mscorlib]System.Object"); ILGen.AddLeftBrace(); for (int i = 0; i < fields.Count; i++) { ILGen.AddLine(".field " + (fields[i].isPublic?"public ":"private ") + (fields[i].isStatic?"static ":" ") + "literal " + fields[i].type + " " + fields[i].name); } foreach (var t in functions) { t.Create(this); } ILGen.AddLine(" .method public hidebysig specialname rtspecialname instance void"); ILGen.AddLine(" .ctor() cil managed "); ILGen.AddLeftBrace(); ILGen.ILNumber = 0; ILGen.preserved = new List <int>(); ILGen.AddLine(".maxstack 8"); for (int i = 0; i < fields.Count; i++) { void Set() { switch (fields[i].type) { case "float32": ILGen.AddInstruct(Instruction.ldc_r4, fields[i].value.Replace("f", "")); break; //TODO } } if (fields[i].isStatic) { Set(); ILGen.AddInstruct(Instruction.stsfld, fields[i].type + " " + name_space.name + "." + name + "::" + fields[i].name); } else { ILGen.AddInstruct(Instruction.ldarg_0); Set(); ILGen.AddInstruct(Instruction.stfld, fields[i].type + " " + name_space.name + "." + name + "::" + fields[i].name); } } ILGen.AddInstruct(Instruction.ret); ILGen.AddRightBrace(); ILGen.AddRightBrace(); }
public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args) { if (args.Length != 1) throw new ArgumentException("Unproperly formated expression"); for (int k = 0; k < st.Count; k++) il.Emit(OpCodes.Pop); engine.CompileExpr(il, locals, st, args[0]); st.Pop(); il.Emit(OpCodes.Ret); st.Push(typeof(System.Object)); }
protected override void EmitClassObjectFromInstance(ILGen il) { if (typeof(IRubyObject).IsAssignableFrom(BaseType)) { il.EmitCall(Methods.IRubyObject_get_ImmediateClass); } else { il.EmitFieldGet(_immediateClassField); } }
public static void EmitDebugInfo(ILGen ilg, IPersistentMap spanMap) { GenContext context = Compiler.CompilerContextVar.deref() as GenContext; if (context == null) { return; } context.MaybeEmitDebugInfo(ilg, spanMap); }
private void GenerateDummyMethod(GenContext context, MethodInfo mi) { TypeBuilder tb = TypeBuilder; MethodBuilder mb = tb.DefineMethod(ExplicitMethodName(mi), MethodAttributes.ReuseSlot | MethodAttributes.Public | MethodAttributes.Virtual, mi.ReturnType, Compiler.GetTypes(mi.GetParameters())); ILGen gen = new ILGen(mb.GetILGenerator()); gen.EmitNew(typeof(NotImplementedException), Type.EmptyTypes); gen.Emit(OpCodes.Throw); tb.DefineMethodOverride(mb, mi); }
private void EmitContext(ILGen /*!*/ il, bool context) { if (context) { il.EmitLoadArg(1); } else { EmitImplicitContext(il); } }
private void EmitConstant(object value, Type type) { // Try to emit the constant directly into IL if (ILGen.CanEmitConstant(value, type)) { _ilg.EmitConstant(value, type); return; } _boundConstants.EmitConstant(this, value, type); }
private Branch GetBranch(List<Branch> branches, ILGen il, Type type) { foreach (Branch b in branches) if (b.type == type) return b; Branch branch = new Branch(); branch.type = type; branch.localVar = il.DeclareLocal(type); branch.handler = il.DefineLabel(); branches.Add(branch); return branch; }
public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args) { if (args.Length != 1 || !Lisp.IsAtom(args[0])) throw new ArgumentException("Unproperly formated expression"); SymbolLink link = engine.Get(args[0]); il.Emit(OpCodes.Ldarg_3); il.Emit(OpCodes.Ldarg_1); il.EmitInt(locals.DefineConstant(link)); il.Emit(OpCodes.Ldelem_Ref); il.EmitCall(m_memoryPoolGetData); st.Push(typeof(System.Object)); }
public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args) { for (int k = 0; k < args.Length; k++) { engine.CompileExpr(il, locals, st, args[k]); if (k > 0) { st.Pop(); il.Emit(OpCodes.Pop); } } }
internal LabelInfo(ILGen il, LabelTarget node, bool canReturn) { _ilg = il; Node = node; Label = il.DefineLabel(); _canReturn = canReturn; if (node != null && node.Type != typeof(void)) { Value = il.DeclareLocal(node.Type); } // Until we have more information, default to a leave instruction, which always works _opCode = OpCodes.Leave; }
public override Type Compile(Executive engine, ILGen il, LocalAccess locals, Type[] parameterTypes) { Label l_true = il.DefineLabel(); Label l_false = il.DefineLabel(); il.Emit(OpCodes.Brfalse_S, l_true); il.EmitNull(); il.Emit(OpCodes.Br_S, l_false); il.MarkLabel(l_true); il.Emit(OpCodes.Ldsfld, typeof(RuntimeOps).GetField("True")); il.MarkLabel(l_false); return typeof(System.Object); }
public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args) { Type resType = null; List<Branch> branches = new List<Branch>(); for (int k = 0; k < args.Length; k++) { Label next = il.DefineLabel(); object cur = args[k]; if (!Lisp.IsCons(cur)) throw new ArgumentException("Unproperly formated expression"); object[] pair = Lisp.ToArray(cur); if (pair.Length != 2) throw new ArgumentException("Unproperly formated expression"); engine.CompileExpr(il, locals, st, pair[0]); if (st.Pop() != typeof(System.Object)) throw new ArgumentException("Expecting boolean value"); il.Emit(OpCodes.Brfalse, next); engine.CompileExpr(il, locals, st, pair[1]); Type type = st.Pop(); Branch branch = GetBranch(branches, il, type); il.Emit(OpCodes.Stloc, branch.localVar); il.Emit(OpCodes.Br, branch.handler); il.MarkLabel(next); if (resType == null) resType = type; else if (resType != type) resType = typeof(System.Object); } il.EmitCall(_raiseError); Label end = il.DefineLabel(); for (int k = 0; k < branches.Count; k++) { Branch b = branches[k]; il.MarkLabel(b.handler); il.Emit(OpCodes.Ldloc, b.localVar); il.FreeLocal(b.localVar); if (resType != b.type) { if (ValueProxy.IsProxyType(b.type)) il.EmitPropertyGet(typeof(ValueProxy), "Value"); else if (b.type.IsValueType) il.Emit(OpCodes.Box, b.type); } if (k < branches.Count -1) il.Emit(OpCodes.Br, end); } il.MarkLabel(end); st.Push(resType); }
internal static ReturnFixer EmitArgument(ILGen cg, int argIndex, Type argType) { cg.EmitLoadArg(argIndex); if (!argType.IsByRef) { cg.EmitBoxing(argType); return null; } Type elementType = argType.GetElementType(); cg.EmitLoadValueIndirect(elementType); Type concreteType = typeof(StrongBox<>).MakeGenericType(elementType); cg.EmitNew(concreteType, new Type[] { elementType }); LocalBuilder refSlot = cg.DeclareLocal(concreteType); cg.Emit(OpCodes.Dup); cg.Emit(OpCodes.Stloc, refSlot); return new ReturnFixer(refSlot, argIndex, argType); }
public override Type Compile(Executive engine, ILGen il, LocalAccess locals, Type[] parameterTypes) { LocalBuilder[] localVar = new LocalBuilder[Name.Arity]; for (int k = Name.Arity -1; k >= 0; k--) { localVar[k] = il.DeclareLocal(Name.Signature[k]); il.Emit(OpCodes.Stloc, localVar[k]); } il.Emit(OpCodes.Ldarg_1); il.EmitInt(locals.DefineConstant(m_delegate)); il.Emit(OpCodes.Ldelem_Ref); il.Emit(OpCodes.Isinst, m_delegate.GetType()); for (int k = 0; k < Name.Arity; k++) { il.Emit(OpCodes.Ldloc, localVar[k]); il.FreeLocal(localVar[k]); } il.EmitCall(m_delegate.GetType(), "Invoke"); return m_delegate.Method.GetReturnType(); }
public override void CreateVariables(Executive engine, object form, ILGen il, LocalAccess locals, object[] args) { if (args.Length == 0) throw new ArgumentException("Unproperly formated expression"); locals.DeclareScope(form); locals.EnterScope(form, _activeScope); foreach (object arg in Lisp.getIterator(args[0])) { object[] pair = Lisp.ToArray(arg); if (pair.Length != 2 || !Lisp.IsAtom(pair[0])) throw new ArgumentException("Unproperly formated expression"); locals.DeclareLocal(pair[0]); engine.CreateVariables(il, locals, pair[1]); } if (!_activeScope) locals.ActivateScope(); for (int k = 1; k < args.Length; k++) engine.CreateVariables(il, locals, args[k]); locals.LeaveScope(); }
public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args) { LambdaExpr lambda = new LambdaExpr(null, locals.Parameters, typeof(System.Object), Lisp.Arg1(form)); lambda.Isolate = false; Type[] parameterTypes = new Type[locals.Parameters.Length]; for (int k = 0; k < parameterTypes.Length; k++) { //LocalBuilder local = locals.GetLocal(locals.Parameters[k].ID); //parameterTypes[k] = local.LocalType; //il.Emit(OpCodes.Ldloc, local); parameterTypes[k] = locals.Parameters[k].Type; il.Emit(OpCodes.Ldarg_2); il.EmitInt(k); il.Emit(OpCodes.Ldelem_Ref); il.Emit(OpCodes.Isinst, parameterTypes[k]); if (parameterTypes[k].IsValueType) il.EmitUnbox(parameterTypes[k]); } st.Push(lambda.Compile(engine, il, locals, parameterTypes)); }
public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args) { if (args.Length != 2) throw new ArgumentException("Unproperly formated expression"); engine.CompileExpr(il, locals, st, args[0]); if (st.Pop() != typeof(System.Object)) throw new ArgumentException("Expecting boolean value"); Label l_false = il.DefineLabel(); il.Emit(OpCodes.Brfalse, l_false); engine.CompileExpr(il, locals, st, args[1]); if (st.Pop() != typeof(System.Object)) throw new ArgumentException("Expecting boolean value"); Label end = il.DefineLabel(); il.Emit(OpCodes.Brfalse_S, l_false); il.Emit(OpCodes.Ldsfld, typeof(RuntimeOps).GetField("True")); il.Emit(OpCodes.Br_S, end); il.MarkLabel(l_false); il.EmitNull(); il.MarkLabel(end); st.Push(typeof(System.Object)); }
internal void Init(ILGen.BaseILGenerator ilGen) { _ilGen = ilGen; if (_availableLocals == null) { //First time initialization _availableLocals = new Dictionary<Type, AvailableLocals>(); _symbolLocals = new Dictionary<JSSymbol, LocalBuilder>(); _namedLocals = new Dictionary<string, LocalBuilder>(); _unnamedLocals = new Dictionary<IR.WriteTemporaryExpression, LocalBuilder>(); _temporaryStackLocals = new List<LocalBuilder>(); } else Debug.Assert( _availableLocals.Count == 0 && _symbolLocals.Count == 0 && _namedLocals.Count == 0 && _unnamedLocals.Count == 0 && _temporaryStackLocals.Count == 0 , "LocalVarManager was not cleared properly in the last use!"); }
public override Type Compile(Executive engine, ILGen il, LocalAccess locals, Type[] parameterTypes) { switch (_case) { case 0: il.Emit(_opcode); break; case 1: il.Emit(_opcode, _type); break; case 2: il.EmitCall(_type, _methodName); break; case 3: il.EmitCall(_type, _methodName, _paramTypes); break; } return _returnType; }
public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args) { locals.EnterScope(form, _activeScope); foreach (object arg in Lisp.getIterator(args[0])) { object[] pair = Lisp.ToArray(arg); engine.CompileExpr(il, locals, st, pair[1]); LocalBuilder localvar = locals.BindLocal(pair[0], st.Pop()); il.Emit(OpCodes.Stloc, localvar); } if (!_activeScope) locals.ActivateScope(); for (int k = 1; k < args.Length; k++) { engine.CompileExpr(il, locals, st, args[k]); if (k < args.Length - 1) { st.Pop(); il.Emit(OpCodes.Pop); } } locals.DestroyScope(); }
private void OverrideDeserializer(ConstructorInfo/*!*/ baseCtor) { // ctor(SerializationInfo! info, StreamingContext! context) : base(info, context) { // RubyOps.DeserializeObject(out this._instanceData, out this._immediateClass, info); // } ConstructorBuilder cb = _tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, _deserializerSignature); ILGen il = new ILGen(cb.GetILGenerator()); il.EmitLoadArg(0); il.EmitLoadArg(1); il.EmitLoadArg(2); il.Emit(OpCodes.Call, baseCtor); il.EmitLoadArg(0); il.EmitFieldAddress(InstanceDataField); il.EmitLoadArg(0); il.EmitFieldAddress(ImmediateClassField); il.EmitLoadArg(1); il.EmitCall(Methods.DeserializeObject); il.Emit(OpCodes.Ret); }
private void BuildConstructors(IList<ConstructorBuilderInfo>/*!*/ ctors) { foreach (var ctor in ctors) { // ctor(... RubyClass! class ..., <visible params>) : base(<hidden params>, <visible params>) { _class = class; } // ctor(... RubyClass! class ..., <visible params>) : base(... RubyOps.GetContextFromClass(class) ..., <visible params>) { _class = class; } // ctor(RubyClass! class) : base(RubyOps.GetDefaultExceptionMessage(class)) { _class = class; } ConstructorBuilder cb = _tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, ctor.ParameterTypes); ILGen il = new ILGen(cb.GetILGenerator()); int paramIndex = 0; int argIndex = 0; // We need to initialize before calling base ctor since the ctor can call virtual methods. // _immediateClass = immediateClass: if (!IsDerivedRubyType) { il.EmitLoadArg(0); il.EmitLoadArg(1 + ctor.ClassParamIndex); il.EmitFieldSet(ImmediateClassField); } // base ctor call: il.EmitLoadArg(0); ConstructorInfo msgCtor; if (ctor.ParameterTypes.Length == 1 && ctor.Adjustment == SignatureAdjustment.InsertClass && _tb.IsSubclassOf(typeof(Exception)) && IsAvailable(msgCtor = _tb.BaseType.GetConstructor(_exceptionMessageSignature))) { // a parameterless exception constructor should use Ruby default message: il.EmitLoadArg(1); il.EmitCall(Methods.GetDefaultExceptionMessage); il.Emit(OpCodes.Call, msgCtor); } else { if (ctor.Adjustment == SignatureAdjustment.InsertClass) { paramIndex++; } while (paramIndex < ctor.ParameterTypes.Length) { if (ctor.Adjustment == SignatureAdjustment.ConvertClassToContext && argIndex == ctor.ContextArgIndex) { il.EmitLoadArg(1 + ctor.ClassParamIndex); il.EmitCall(Methods.GetContextFromModule); } else { ClsTypeEmitter.DefineParameterCopy(cb, paramIndex, ctor.BaseParameters[argIndex]); il.EmitLoadArg(1 + paramIndex); } argIndex++; paramIndex++; } il.Emit(OpCodes.Call, ctor.BaseCtor); } il.Emit(OpCodes.Ret); } }
static MethodBuilder GenerateGetRequiredArityMethod(TypeBuilder tb, int requiredArity) { MethodBuilder mb = tb.DefineMethod( "getRequiredArity", MethodAttributes.ReuseSlot | MethodAttributes.Public | MethodAttributes.Virtual, typeof(int), Type.EmptyTypes); ILGen gen = new ILGen(mb.GetILGenerator()); gen.EmitInt(requiredArity); gen.Emit(OpCodes.Ret); return mb; }
/// <summary> /// Generates stub to receive the CLR call and then call the dynamic language code. /// </summary> private object[] EmitClrCallStub(ILGen cg) { List<ReturnFixer> fixers = new List<ReturnFixer>(0); // Create strongly typed return type from the site. // This will, among other things, generate tighter code. Type[] siteTypes = MakeSiteSignature(); CallSite callSite = CallSite.Create(DynamicSiteHelpers.MakeCallSiteDelegate(siteTypes), InvokeBinder); Type siteType = callSite.GetType(); Type convertSiteType = null; CallSite convertSite = null; if (_returnType != typeof(void)) { convertSite = CallSite.Create(DynamicSiteHelpers.MakeCallSiteDelegate(typeof(object), _returnType), ConvertBinder); convertSiteType = convertSite.GetType(); } // build up constants array object[] constants = new object[] { TargetPlaceHolder, CallSitePlaceHolder, ConvertSitePlaceHolder }; const int TargetIndex = 0, CallSiteIndex = 1, ConvertSiteIndex = 2; LocalBuilder convertSiteLocal = null; FieldInfo convertTarget = null; if (_returnType != typeof(void)) { // load up the conversesion logic on the stack convertSiteLocal = cg.DeclareLocal(convertSiteType); EmitConstantGet(cg, ConvertSiteIndex, convertSiteType); cg.Emit(OpCodes.Dup); cg.Emit(OpCodes.Stloc, convertSiteLocal); convertTarget = convertSiteType.GetField("Target"); cg.EmitFieldGet(convertTarget); cg.Emit(OpCodes.Ldloc, convertSiteLocal); } // load up the invoke logic on the stack LocalBuilder site = cg.DeclareLocal(siteType); EmitConstantGet(cg, CallSiteIndex, siteType); cg.Emit(OpCodes.Dup); cg.Emit(OpCodes.Stloc, site); FieldInfo target = siteType.GetField("Target"); cg.EmitFieldGet(target); cg.Emit(OpCodes.Ldloc, site); EmitConstantGet(cg, TargetIndex, typeof(object)); for (int i = 0; i < _parameters.Length; i++) { if (_parameters[i].ParameterType.IsByRef) { ReturnFixer rf = ReturnFixer.EmitArgument(cg, i + 1, _parameters[i].ParameterType); if (rf != null) fixers.Add(rf); } else { cg.EmitLoadArg(i + 1); } } // emit the invoke for the call cg.EmitCall(target.FieldType, "Invoke"); // emit the invoke for the convert if (_returnType == typeof(void)) { cg.Emit(OpCodes.Pop); } else { cg.EmitCall(convertTarget.FieldType, "Invoke"); } // fixup any references foreach (ReturnFixer rf in fixers) { rf.FixReturn(cg); } cg.Emit(OpCodes.Ret); return constants; }
private static void EmitUnsupported(ILGen gen, string name) { gen.EmitString(name); // gen.Emit(OpCodes.Ldstr, name); gen.EmitNew(CtorInfo_NotImplementedException_1); // gen.Emit(OpCodes.Newobj, CtorInfo_NotImplementedException_1); gen.Emit(OpCodes.Throw); }
static void EmitMain(GenContext context, TypeBuilder proxyTB, string mainName, FieldBuilder mainFB) { MethodBuilder cb = proxyTB.DefineMethod("Main",MethodAttributes.Public| MethodAttributes.Static,CallingConventions.Standard,typeof(void),new Type[] { typeof(String[]) }); ILGen gen = new ILGen(cb.GetILGenerator()); ; Label noMainLabel = gen.DefineLabel(); Label endLabel = gen.DefineLabel(); EmitGetVar(gen, mainFB); gen.Emit(OpCodes.Dup); gen.Emit(OpCodes.Brfalse_S, noMainLabel); gen.Emit(OpCodes.Castclass, typeof(IFn)); gen.EmitLoadArg(0); // gen.Emit(OpCodes.Ldarg_0); gen.EmitCall(Method_RT_seq); // gen.Emit(OpCodes.Call, Method_RT_seq); gen.EmitCall(Method_IFn_applyTo_Object_ISeq); // gen.Emit(OpCodes.Call, Method_IFn_applyTo_Object_ISeq); gen.Emit(OpCodes.Pop); gen.Emit(OpCodes.Br_S, endLabel); // no main found gen.MarkLabel(noMainLabel); EmitUnsupported(gen, mainName); gen.MarkLabel(endLabel); gen.Emit(OpCodes.Ret); //context.AssyBldr.SetEntryPoint(cb); context.AssemblyBuilder.SetEntryPoint(cb); }
static void EmitGetVar(ILGen gen, FieldBuilder fb) { Label falseLabel = gen.DefineLabel(); Label endLabel = gen.DefineLabel(); gen.EmitFieldGet(fb); // gen.Emit(OpCodes.Ldsfld,fb); gen.Emit(OpCodes.Dup); gen.EmitCall(Method_Var_isBound); // gen.Emit(OpCodes.Call, Method_Var_IsBound); gen.Emit(OpCodes.Brfalse_S,falseLabel); gen.Emit(OpCodes.Call,Method_Var_get); gen.Emit(OpCodes.Br_S,endLabel); gen.MarkLabel(falseLabel); gen.Emit(OpCodes.Pop); gen.EmitNull(); // gen.Emit(OpCodes.Ldnull); gen.MarkLabel(endLabel); }