public static void ExecuteAsValueType(MethodGen m) { var g = m.GetCode(); var localObj = g.Local(typeof(object)); g.Assign(localObj, g.ExpressionFactory.New(typeof(MemoryStream))); g.ThrowAssert(!localObj.Is(typeof(int)), "Is MS"); }
public static void UnwrapNullableNull(MethodGen m) { var g = m.GetCode(); var nullable = g.Local(typeof(int?)); var result = g.Local(typeof(int)); g.Assign(nullable, null); g.Assign(result, nullable.Cast(typeof(int))); }
public static void UnwrapNullableImplicit(MethodGen m) { var g = m.GetCode(); var nullable = g.Local(typeof(int?)); var result = g.Local(typeof(int)); g.Assign(nullable, 123); g.Assign(result, nullable); g.ThrowAssert(result == 123); }
public static void ExecuteAddConvertable(MethodGen m) { var g = m.GetCode(); var a = g.Local(typeof(int?)); var b = g.Local(typeof(long?)); g.Assign(a, 1); g.Assign(b, a + (long)1); g.ThrowAssert(b == (long)2, "2"); g.ThrowAssert(b == 2, "2"); }
public static void ExecuteUnbox(MethodGen m) { var g = m.GetCode(); var boxed = g.Local(typeof(object)); var nullable = g.Local(typeof(int?)); g.Assign(boxed, 1); g.Assign(nullable, boxed.Cast(nullable.GetReturnType())); g.ThrowAssert(nullable != null, "!=null"); g.ThrowAssert(nullable == 1, "1"); }
public MethodGen AddMethod(string parameterName) { if (adder == null) { adder = new MethodGen(owner, "add_" + name, attrs | MethodAttributes.SpecialName, typeof(void), 0); adder.Parameter(type, parameterName); eb.SetAddOnMethod(adder.GetMethodBuilder()); } return adder; }
public static void CounterCondition(MethodGen m) { var g = m.GetCode(); var counter = g.Local(10); g.DoWhile(); { g.Decrement(counter); } g.EndDoWhile(counter >= 0); g.ThrowAssert(counter == -1); }
public MethodGen RemoveMethod(string parameterName) { if (remover == null) { remover = new MethodGen(owner, "remove_" + name, attrs | MethodAttributes.SpecialName, typeof(void), 0); remover.Parameter(type, parameterName); eb.SetRemoveOnMethod(remover.GetMethodBuilder()); } return remover; }
public static void ExecuteWithNullable(MethodGen m) { var g = m.GetCode(); var localInt = g.Local(typeof(int?)); g.Assign(localInt, 123); var test = g.Local(12); //var l12=g.Local(12); //var l13=g.Local(13); //var l14=g.Local(14); //var l15=g.Local(15); //g.If(l12 == l13 || l15 <= l14 || ((l15 < l14) && (l15 == 1 || l15 == 2 || localInt != null) && l12 == 2)); var ok = g.Local(typeof(bool)); g.If(localInt != null); { g.Assign(ok, true); } g.Else(); { g.ThrowAssert(false, "if2"); } g.End(); g.ThrowAssert(ok, "if1"); g.If((localInt == null).LogicalAnd(test.Eq(test))); { g.ThrowAssert(false, "if2-1"); } g.End(); g.If(localInt != null); { } g.Else(); { g.ThrowAssert(false, "if3"); } g.End(); g.If(localInt == null); { g.ThrowAssert(false, "if4"); } g.Else(); { } g.End(); g.ThrowAssert(localInt != null, "localInt != null"); g.Assign(localInt, null); g.ThrowAssert(localInt == null, "localInt == null"); }
public MethodGen Getter() { if (getter == null) { LockSignature(); getter = new MethodGen(owner, "get_" + name, attrs | MethodAttributes.SpecialName, type, 0); getter.ImplementedInterface = interfaceType; getter.CopyParameters(indexParameters); pb.SetGetMethod(getter.GetMethodBuilder()); } return getter; }
public static void FalseCondition(MethodGen m) { var g = m.GetCode(); var local = g.Local(false); var counter = g.Local(0); g.DoWhile(); { g.Assign(local, true); g.Increment(counter); } g.EndDoWhile(false); g.ThrowAssert(counter == 1); g.ThrowAssert(local == true); }
public dynamic Visit(Program program) { foreach (var t in program.GlobalVariables) { Visit(t); } foreach (var impl in program.FuncImplementations) { _currentMethod = _currentProgram.Public.Method(impl.ReturnType.CodeGenType(), impl.Name); Visit((dynamic)impl); } return(null); }
public static void ExecuteAdd(MethodGen m) { var g = m.GetCode(); var a = g.Local(typeof(int?)); var b = g.Local(typeof(int?)); g.ThrowAssert(a + 1 != 0, "!=0"); g.ThrowAssert(!(a + 1 == 0), "!(==0)"); g.Assign(a, 1); g.ThrowAssert(a + 1 == 2, "=="); g.ThrowAssert(a == 1, "1"); g.Assign(b, a + 1); g.ThrowAssert(b == 2, "2"); }
private void EmitMethod(NonTerm nonTerm) { Token typeMethodDeclSimple; Token methodName; List <BaseSymbol> formalParametersList; BaseSymbol methodStatementList; BaseSymbol returnStatement; NonTermFactory.GetMethodDecl(nonTerm, out typeMethodDeclSimple, out methodName, out formalParametersList, out methodStatementList, out returnStatement); _currentFormalArgumentList.Clear(); foreach (BaseSymbol symbol in formalParametersList) { Token type; Token id; NonTermFactory.GetFormalArgumentDeclaration(symbol, out type, out id); _currentFormalArgumentList.Add(id.Value); } _compilerLogger.PrintRefreshFormalArgumentList(_currentFormalArgumentList); _currentMethod = _methodsTables[_currentClass.Name][methodName.Value]; _g = _currentMethod; GeneratePreInitLocalVariables(methodStatementList); Generate(methodStatementList); Type resultType = GetVariableType(typeMethodDeclSimple); string nameResult = AddTempLocalVariable(resultType); EmitExpression(returnStatement, resultType, nameResult); try { _g.Return(_currentOperandTempResult); } catch (InvalidCastException ex) { throw new CodeGenerationException(MessagesHelper.TypeMismatchEx, returnStatement.ToStringInfo(), ex); } ClearCurrentBlockLocalVariables(); }
public static void ExecuteWrapNullable(MethodGen m) { var g = m.GetCode(); var localIntNullable = g.Local(typeof(int?)); var localInt = g.Local(typeof(int)); g.Assign(localInt, 123); g.Assign(localIntNullable, localInt); // branch g.ThrowAssert(localIntNullable != null, "localIntNullable != null"); g.ThrowAssert(localIntNullable == localInt, "localIntNullable == localInt"); g.ThrowAssert(localIntNullable == 123, "localIntNullable == 123"); g.ThrowAssert(localIntNullable != 1234, "localIntNullable != 1234"); // condition g.DebugAssert(localIntNullable != null, "localIntNullable != null"); g.DebugAssert(localIntNullable == localInt, "localIntNullable == localInt"); g.DebugAssert(localIntNullable == 123, "localIntNullable == 123"); g.DebugAssert(localIntNullable != 1234, "localIntNullable != 1234"); }
public static void ExecuteIsInst(MethodGen m) { var g = m.GetCode(); var localObj = g.Local(typeof(object)); var localStream = g.Local(typeof(Stream)); g.Assign(localObj, g.ExpressionFactory.New(typeof(MemoryStream))); g.DebugAssert(true, "True"); g.DebugAssert(localObj.Is(typeof(MemoryStream)), "Is MS"); g.DebugAssert(localObj.Is(typeof(MemoryStream)) == true, "Is MS true"); g.DebugAssert(localObj.Is(typeof(Stream)), "Is MS"); g.DebugAssert(localObj.Is(typeof(Stream)) == true, "Is MS true"); g.DebugAssert(!localObj.Is(typeof(ArrayList)), "Is NOT ArrayList"); g.DebugAssert(localObj.Is(typeof(ArrayList)) == false, "Is NOT ArrayList true"); g.Invoke(localObj.As(typeof(Stream)), "WriteByte", 123); g.DebugAssert(localObj.As(typeof(Stream)).Property("Length") == 1); g.Assign(localStream, localObj.As(typeof(Stream))); g.DebugAssert(localStream.Property("Position") == 1, "Position"); }
public static void And(MethodGen m) { var g = m.GetCode(); Operand l1 = 1; Operand l2 = 2; Operand l3 = 3; Operand l4 = 4; g.If((l1 == l1) && (l2 == l2)); { g.Return(); } g.Else(); { g.ThrowAssert(false, "Equality"); } g.End(); g.ThrowAssert(false, "Not returned"); }
public static void ExecuteWithValueType(MethodGen m) { var g = m.GetCode(); var localInt = g.Local(typeof(int)); g.Assign(localInt, 123); g.If(localInt == null); { g.ThrowAssert(false, "If"); } g.End(); g.DebugAssert(true, "true"); g.ThrowAssert(true, "true"); g.If(localInt != null); g.Else(); g.ThrowAssert(false, "localInt != null"); g.End(); }
public static void OrInAnd4(MethodGen m) { var g = m.GetCode(); Operand l1 = 1; Operand l2 = 2; Operand l3 = 3; Operand l4 = 4; g.If((l4 == l3) && (l2 == l2 || l1 == l2)); { g.ThrowAssert(false, "Equality"); } g.Else(); { g.Return(); } g.End(); g.ThrowAssert(false, "Not returned"); }
public static void And2(MethodGen m) { var g = m.GetCode(); Operand l1 = 1; Operand l2 = 2; Operand l3 = 3; Operand l4 = 4; g.If(l1 == l1 && l2 == l3); { g.ThrowAssert(false, "Equality"); } g.Else(); { g.Return(); } g.End(); g.ThrowAssert(false, "Not returned"); }
public static void ExecuteValueType(MethodGen m) { var g = m.GetCode(); var localObj = g.Local(typeof(object)); g.Assign(localObj, 1); g.DebugAssert(localObj.Is(typeof(int)), "Is int"); g.DebugAssert(!localObj.Is(typeof(long)), "Is long"); g.DebugAssert(!localObj.Is(typeof(long?)), "Is long?"); g.DebugAssert(localObj.As(typeof(int)) == 1, "1"); g.DebugAssert(localObj.As(typeof(int)) != 2, "21"); g.DebugAssert(localObj.As(typeof(int?)) != 2, "22"); g.DebugAssert(localObj.As(typeof(int?)) == 1, "23"); g.ThrowAssert(localObj.Is(typeof(int)), "Is int"); g.ThrowAssert(!localObj.Is(typeof(long)), "Is long"); g.ThrowAssert(!localObj.Is(typeof(long?)), "Is long?"); g.ThrowAssert(localObj.As(typeof(int)) == 1, "1"); g.ThrowAssert(localObj.As(typeof(int)) != 2, "21"); g.ThrowAssert(localObj.As(typeof(int?)) != 2, "22"); g.ThrowAssert(localObj.As(typeof(int?)) == 1, "23"); }
public static void ExecuteConditionalInt(MethodGen m) { var g = m.GetCode(); var localInt = g.Local(typeof(int)); g.Assign(localInt, 123); g.Assign( localInt, ((Operand)true).Conditional(((Operand)true).Conditional(124, 0), ((Operand)true).Conditional(125, 1))); g.DebugAssert(localInt == 124); //g.If(localInt == null); //{ // g.ThrowAssert(false, "If"); //} //g.End(); //g.DebugAssert(true, "true"); //g.ThrowAssert(true, "true"); //g.If(localInt != null); //g.Else(); //g.ThrowAssert(false, "localInt != null"); //g.End(); }
private KeyValuePair <string, MethodGen> GenerateMethodSignature(TypeGen classDeclaration, BaseSymbol nonTerm, AssemblyGen ag) { Token typeMethodDeclSimple; Token methodName; List <BaseSymbol> formalParametersList; NonTermFactory.GetMethodSignature(nonTerm, out typeMethodDeclSimple, out methodName, out formalParametersList); Type methodReturnType = GetVariableType(typeMethodDeclSimple); MethodGen method = classDeclaration.Public.Method(methodReturnType, methodName.Value); foreach (BaseSymbol symbol in formalParametersList) { Token type; Token id; NonTermFactory.GetFormalArgumentDeclaration(symbol, out type, out id); method.Parameter(GetVariableType(type), id.Value); } //_compilerLogger.PrintAddtFormalArgumentList(formalParametersList.Select(s => s.Symbols[1].Value).ToList()); return(new KeyValuePair <string, MethodGen>(methodName.Value, method)); }
public static void ReplaceJunkInSource(string filePath) { StringBuilder sb = new StringBuilder(); MethodGen mtdGen = new MethodGen(); string[] fileSource = File.ReadAllLines(filePath); for (int i = 0; i < fileSource.Length; i++) { if (fileSource[i].Contains(StringConstants.STR_JUNK)) { for (int x = 0; x < Rand.Next(10, 20); x++) { sb.AppendLine(mtdGen.RandMethod()); } fileSource[i] = sb.ToString(); sb = new StringBuilder(); } } File.WriteAllLines(filePath, fileSource); }
public MethodGen AddMethod(string parameterName) { if (_adder == null) { LockSignature(); _adder = new MethodGen(_owner, "add_" + Name, _attrs | MethodAttributes.SpecialName, TypeMapper.MapType(typeof(void)), 0); _adder.ImplementedInterface = ImplementedInterface; _adder.Parameter(_type, parameterName); _eb.SetAddOnMethod(_adder.GetMethodBuilder()); } return _adder; }
public static void ExecuteIncrementNullable(MethodGen m) { var g = m.GetCode(); var localIntNullable = g.Local(typeof(int?)); g.Assign(localIntNullable, 1); g.Increment(localIntNullable); // condition g.ThrowAssert(localIntNullable == 2, "2"); }
/// <summary> /// Create a wrapper class for a generic interface with more general type parameters than the wrapped interface. /// Downcasts to the correct more specific type are generated where necessary. /// This of course breaks type safety, and only calls to the class with the correct orginal types will work. /// Incorrect calls will throw <see cref = "InvalidCastException" />. /// </summary> /// <remarks> /// This is useful during reflection, when you don't want to know about specific types, but you can guarantee /// that a certain call will always be done with objects of the correct type. /// TODO: This non-generic method is only needed since RunSharp can't call generic methods, needed to generate wrappers recursively. /// TODO: Possibly Castle DynamicProxy could replace this if it allows creating 'non-matching' proxies and thus support the downcasting. /// </remarks> /// <param name = "typeToCreate">The less-specific generic type of the wrapper which will be generated.</param> /// <param name = "o">The object to wrap, which should implement the desired interface, with arbitrary type parameters.</param> /// <returns>An instance of the specified type which wraps the given object.</returns> public static object CreateGenericInterfaceWrapper(Type typeToCreate, object o) { Contract.Requires(o.GetType().IsOfGenericType(typeToCreate.GetGenericTypeDefinition())); Contract.Requires(typeToCreate.IsInterface); Type typeToCreateGeneric = typeToCreate.GetGenericTypeDefinition(); Type innerType = o.GetType(); Type innerMatchingType = innerType.GetMatchingGenericType(typeToCreateGeneric); // Implement passed type and redirect all public calls to inner instance. var assembly = new AssemblyGen("Whathecode.System.RunSharp"); TypeGen type = assembly.Public.Class("Wrapped" + typeToCreate.Name, typeof(object), typeToCreate); { const string inner = "inner"; FieldGen innerInstance = type.Private.Field(innerType, "_innerInstance"); FieldGen returnCached = type.Private.Field(typeof(Dictionary <int, object>), "_returnCached"); FieldGen returnWrappers = type.Private.Field(typeof(Dictionary <int, object>), "_returnWrappers"); // Create constructor which takes the wrapped instance as an argument. ConstructorGen constructor = type.Public.Constructor(); { constructor.Parameter(innerType, inner); CodeGen code = constructor.GetCode(); { code.Assign(innerInstance, code.Arg(inner)); code.Assign(returnCached, Exp.New(typeof(Dictionary <int, object>))); code.Assign(returnWrappers, Exp.New(typeof(Dictionary <int, object>))); } } // Create methods. int methodCount = 0; MethodInfo[] innerMethods = innerMatchingType.GetFlattenedInterfaceMethods(ReflectionHelper.FlattenedInstanceMembers).ToArray(); MethodInfo[] toCreateMethods = typeToCreate.GetFlattenedInterfaceMethods(ReflectionHelper.FlattenedInstanceMembers).ToArray(); MethodInfo[] genericMethods = typeToCreateGeneric.GetFlattenedInterfaceMethods(ReflectionHelper.FlattenedInstanceMembers).ToArray(); foreach (var method in innerMethods .Zip(toCreateMethods, genericMethods, (matching, toCreate, generic) => new { Id = methodCount++, Matching = matching, ToCreate = toCreate, Generic = generic }) .Where(z => z.Matching.IsPublic || z.Matching.IsFamily)) { // TODO: Not quite certain why override is required for extended interfaces (DeclaringType != typeTocreate), // but this seems to work. MethodInfo toCreate = method.ToCreate; MethodGen methodGen = toCreate.DeclaringType == typeToCreate ? type.MethodImplementation(typeToCreate, toCreate.ReturnType, toCreate.Name) : type.Public.Override.Method(toCreate.ReturnType, toCreate.Name); { ParameterInfo[] toCreateParameters = toCreate.GetParameters(); var parameters = toCreateParameters .Select(p => { var info = methodGen.BeginParameter(p.ParameterType, p.Name); info.End(); return(info); }).ToArray(); CodeGen code = methodGen.GetCode(); { // Cast arguments to the type of the inner instance. Operand[] args = parameters.Select(p => code.Arg(p.Name)).ToArray(); Operand[] castArgs = { }; if (args.Length > 0) { Type[] parameterTypes = method.Matching.GetParameters().Select(p => p.ParameterType).ToArray(); // TODO: When searching for generic methods, GetMethod returns null. http://stackoverflow.com/questions/4035719/getmethod-for-generic-method // Even when the correct method is found through custom filtering, RunSharp does not seem to be able to create generic methods yet. MethodInfo methodToCall = innerType.GetMethod(toCreate.Name, ReflectionHelper.FlattenedInstanceMembers, parameterTypes); castArgs = methodToCall.GetParameters() .Select((p, index) => args[index].Cast(typeof(object)).Cast(p.ParameterType)).ToArray(); } // Call inner instance and return value when needed. if (toCreate.ReturnType != typeof(void)) { Operand result = innerInstance.Invoke(toCreate.Name, castArgs); // Wrappers will recursively need to be created for generic return types. Type genericReturnType = method.Generic.ReturnType; if (genericReturnType.IsGenericType && genericReturnType.ContainsGenericParameters && genericReturnType.IsInterface) { // Check whether a new result is returned. Operand innerCached = code.Local(typeof(object)); code.If(returnCached.Invoke("TryGetValue", method.Id, innerCached.Ref())); { code.If((innerCached == result).LogicalNot()); { code.Invoke(returnWrappers, "Remove", method.Id); code.Invoke(returnCached, "Remove", method.Id); code.Invoke(returnCached, "Add", method.Id, result); } code.End(); } code.Else(); { code.Invoke(returnCached, "Add", method.Id, result); } code.End(); // Check whether a wrapper needs to be generated. Operand wrappedCached = code.Local(typeof(object)); code.If(returnWrappers.Invoke("TryGetValue", method.Id, wrappedCached.Ref()).LogicalNot()); { Operand proxied = Static.Invoke(typeof(Proxy), "CreateGenericInterfaceWrapper", toCreate.ReturnType, result); code.Assign(wrappedCached, proxied); code.Invoke(returnWrappers, "Add", method.Id, wrappedCached); } code.End(); code.Return(wrappedCached.Cast(toCreate.ReturnType)); } else { // A simple cast will work. // TODO: Throw proper exception when this is known to fail. E.g. generic type which is not an interface? code.Return(result.Cast(toCreate.ReturnType)); } } else { code.Invoke(innerInstance, toCreate.Name, castArgs); } } } } } Type wrapperType = type.GetCompletedType(true); return(Activator.CreateInstance(wrapperType, new[] { o })); }
public MethodGen Getter() { if (_getter == null) { LockSignature(); _getter = new MethodGen(_owner, "get_" + Name, _attrs | MethodAttributes.SpecialName, _type, 0); _getter.ImplementedInterface = ImplementedInterface; _getter.CopyParameters(_indexParameters); _pb.SetGetMethod(_getter.GetMethodBuilder()); } return _getter; }
public static void ExecuteCompareNullables(MethodGen m) { var g = m.GetCode(); var a = g.Local(typeof(int?)); var b = g.Local(typeof(int?)); g.ThrowAssert(a == b, "a==b"); g.Assign(a, 1); g.ThrowAssert(a != b, "a!=b 1"); g.ThrowAssert(a == 1, "a==1"); g.ThrowAssert(b != 1, "b!=1"); g.ThrowAssert(a >= 1, "a !>="); g.ThrowAssert(!(a < 1), "a !<"); g.ThrowAssert(!(b > 1), "!>"); g.ThrowAssert(!(b < 1), "!<"); g.Assign(b, 1); g.ThrowAssert(a == b, "a==b"); g.ThrowAssert(!(a > 1), "!>"); g.ThrowAssert(!(a < 1), "!<"); g.Assign(b, 2); g.ThrowAssert(a != b, "a!=b 3"); g.ThrowAssert(a < b, "<"); g.ThrowAssert(a <= b, ">="); g.ThrowAssert(!(a > b), "!>"); }
public static void ExecuteBoxNull(MethodGen m) { var g = m.GetCode(); var boxed = g.Local(typeof(object)); var nullable = g.Local(typeof(int?)); g.Assign(nullable, null); g.Assign(boxed, nullable); g.ThrowAssert(boxed == null, "null"); }
public static void ExecuteBox(MethodGen m) { var g = m.GetCode(); var boxed = g.Local(typeof(object)); var nullable = g.Local(typeof(int?)); g.Assign(nullable, 1); g.Assign(boxed, nullable); g.ThrowAssert(boxed.Cast(typeof(int)) == 1, "1"); }
public static void ExecuteUnboxNull(MethodGen m) { var g = m.GetCode(); var boxed = g.Local(typeof(object)); var nullable = g.Local(typeof(int?)); g.Assign(boxed, null); g.Assign(nullable, boxed.Cast(nullable.GetReturnType())); g.ThrowAssert(nullable == null, "is null"); }
public static void ExecuteCast(MethodGen m) { var g = m.GetCode(); var a = g.Local(typeof(long?)); var b = g.Local(typeof(int?)); g.Assign(a, 1); g.Assign(b, a.Cast(typeof(int?))); g.ThrowAssert(b == 1, "1"); }
public static void ExecuteAssignNonNullableImplicit(MethodGen m) { var g = m.GetCode(); var a = g.Local(typeof(long?)); var b = g.Local(typeof(int)); g.Assign(b, 1); g.Assign(a, b); g.ThrowAssert(b == 1, "1"); }
public MethodGen Setter() { if (setter == null) { LockSignature(); setter = new MethodGen(owner, "set_" + name, attrs | MethodAttributes.SpecialName, typeof(void), 0); setter.ImplementedInterface = interfaceType; setter.CopyParameters(indexParameters); setter.UncheckedParameter(type, "value"); pb.SetSetMethod(setter.GetMethodBuilder()); } return setter; }
public MethodGen Setter() { if (_setter == null) { LockSignature(); _setter = new MethodGen(_owner, "set_" + Name, _attrs | MethodAttributes.SpecialName, TypeMapper.MapType(typeof(void)), 0); _setter.ImplementedInterface = ImplementedInterface; _setter.CopyParameters(_indexParameters); _setter.UncheckedParameter(_type, "value"); _pb.SetSetMethod(_setter.GetMethodBuilder()); } return _setter; }