/// <summary> /// Add the given method to its declaring class. /// </summary> protected override void SetAccessFlags(DexLib.MethodDefinition dmethod, MethodDefinition method) { dmethod.IsStatic = true; dmethod.IsPublic = true; if (method.IsAbstract || method.IsVirtual) { // generate a warning, since these methods will never be called // as virtual. Do not generate a warning if we know the compiler // will handle the call. if (method.DeclaringType.FullName == "System.Array") { // all array methods should be redirected by the compiler. return; } var intfMethod = method.GetBaseInterfaceMethod(); if (intfMethod != null && intfMethod.DeclaringType.FullName == "System.IFormattable") { // this is handled by the compiler. return; } DLog.Warning(DContext.CompilerCodeGenerator, "Abstract or virtual .NET method '{0}' in DexImport class '{1}'. Unless specially handled by the compiler, this will never be called virtually.", method.Name, method.DeclaringType.FullName); } }
/// <summary> /// IL ctor /// </summary> public MethodSource(XMethodDefinition method, ILMethodDefinition ilMethod) { if (ilMethod == null) throw new ArgumentNullException(); this.method = method; this.ilMethod = ilMethod; }
public InstructionElement(Mono.Cecil.MethodDefinition parentMethod, InstructionElement[] childnodes, Mono.Cecil.Cil.Instruction instruction) { this.Childnodes = childnodes ?? new InstructionElement[0]; this.Instruction = instruction; this.ParentMethod = parentMethod; foreach (InstructionElement c in this.Childnodes) { System.Diagnostics.Trace.Assert(c != null); c.Parent = this; } if (instruction != null) AssignReturnType(); }
public static ProductException GetMT4127 (TMethod impl, List<TMethod> ifaceMethods) { var msg = new System.Text.StringBuilder (); msg.Append ("Cannot register more than one interface method for the method '"); msg.Append (impl.DeclaringType.FullName).Append ('.').Append (impl.Name); msg.Append ("' (which is implementing '"); for (int i = 0; i < ifaceMethods.Count; i++) { if (i > 0) msg.Append (i < ifaceMethods.Count - 1 ? "', '" : "' and '"); var ifaceM = ifaceMethods [i]; msg.Append (ifaceM.DeclaringType.FullName).Append ('.').Append (ifaceM.Name); } msg.Append ("')."); return ErrorHelper.CreateError (4127, msg.ToString ()); }
void RemoveInstruction(MethodDefinition method, Func <Instruction, bool> where) { var il = method.Body.GetILProcessor(); il.Remove(method.Body.Instructions.First(where)); }
/// <summary> /// Default ctor /// </summary> public DexImportMethodBuilder(AssemblyCompiler compiler, MethodDefinition method) : base(compiler, method) { }
public bool IsAppCall(Mono.Cecil.MethodDefinition defs, out byte[] hash) { if (defs == null) { hash = null; return(false); } foreach (var attr in defs.CustomAttributes) { if (attr.AttributeType.Name == "AppcallAttribute") { var type = attr.ConstructorArguments[0].Type; var a = attr.ConstructorArguments[0]; if (a.Type.FullName == "System.String") { string hashstr = (string)a.Value; try { hash = new byte[20]; if (hashstr.Length < 40) { throw new Exception("hash too short:" + hashstr); } for (var i = 0; i < 20; i++) { hash[i] = byte.Parse(hashstr.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber); } //string hexhash 需要反序 hash = hash.Reverse().ToArray(); return(true); } catch { throw new Exception("hex format error:" + hashstr); } } else { var list = a.Value as Mono.Cecil.CustomAttributeArgument[]; if (list == null || list.Length < 20) { throw new Exception("hash too short."); } hash = new byte[20]; for (var i = 0; i < 20; i++) { hash[i] = (byte)list[i].Value; } //byte hash 需要反序 hash = hash.Reverse().ToArray(); //dosth return(true); } } //if(attr.t) } hash = null; return(false); }
public IMethod GetMethod(object token) { IMethod __method = null; if (methodCache.TryGetValue(token.GetHashCode(), out __method)) { return(__method); } Mono.Cecil.ModuleDefinition module = null; string methodname = null; string typename = null; MethodParamList genlist = null; MethodParamList list = null; if (token is Mono.Cecil.MethodReference) { Mono.Cecil.MethodReference _ref = (token as Mono.Cecil.MethodReference); module = _ref.Module; methodname = _ref.Name; typename = _ref.DeclaringType.FullName; list = new MethodParamList(environment, _ref); if (_ref.IsGenericInstance) { Mono.Cecil.GenericInstanceMethod gmethod = _ref as Mono.Cecil.GenericInstanceMethod; genlist = new MethodParamList(environment, gmethod); } } else if (token is Mono.Cecil.MethodDefinition) { Mono.Cecil.MethodDefinition _def = token as Mono.Cecil.MethodDefinition; module = _def.Module; methodname = _def.Name; typename = _def.DeclaringType.FullName; list = new MethodParamList(environment, _def); if (_def.IsGenericInstance) { throw new NotImplementedException(); //Mono.Cecil.GenericInstanceMethod gmethod = _def as Mono.Cecil.GenericInstanceMethod; //genlist = new MethodParamList(environment, gmethod); } } else { throw new NotImplementedException(); } var typesys = GetType(typename); if (typesys == null) { throw new Exception("type can't find:" + typename); } IMethod _method = null; if (genlist != null) { _method = typesys.GetMethodT(methodname, genlist, list); } else { _method = typesys.GetMethod(methodname, list); } methodCache[token.GetHashCode()] = _method; return(_method); }
void FillTree_Method(Mono.Cecil.MethodDefinition method) { treeView2.Tag = method; treeView2.Nodes.Clear(); TreeNode methodinfo = new TreeNode(method.ToString()); treeView2.Nodes.Add(methodinfo); if (method.HasParameters) { TreeNode paraminfo = new TreeNode("Params"); treeView2.Nodes.Add(paraminfo); for (int i = 0; i < method.Parameters.Count; i++) { TreeNode p = new TreeNode(method.Parameters[i].ParameterType + " " + method.Parameters[i].Name); paraminfo.Nodes.Add(p); } } TreeNode body = new TreeNode("Body"); treeView2.Nodes.Add(body); if (method.HasBody) { TreeNode variables = new TreeNode("Variables"); body.Nodes.Add(variables); if (method.Body.HasVariables) { foreach (var v in method.Body.Variables) { TreeNode var = new TreeNode(v.VariableType + " " + v.Name); variables.Nodes.Add(var); } } TreeNode eh = new TreeNode("ExceptionHandlers"); body.Nodes.Add(eh); if (method.Body.HasExceptionHandlers) { foreach (Mono.Cecil.Cil.ExceptionHandler v in method.Body.ExceptionHandlers) { TreeNode var = new TreeNode(v.ToString()); eh.Nodes.Add(v.HandlerType + " " + v.CatchType + "(" + v.HandlerStart + "," + v.HandlerEnd + ")"); } } TreeNode code = new TreeNode("Code"); body.Nodes.Add(code); foreach (Mono.Cecil.Cil.Instruction i in method.Body.Instructions) { string line = i.ToString(); //i.Offset if (i.SequencePoint != null) { LoadCodeFile(i.SequencePoint.Document.Url); line += " |(" + i.SequencePoint.StartLine + "," + i.SequencePoint.StartColumn + ")"; if (codes[i.SequencePoint.Document.Url] != null) { int lines = i.SequencePoint.StartLine; if (lines - 1 < codes[i.SequencePoint.Document.Url].Length) { line += "| " + codes[i.SequencePoint.Document.Url][i.SequencePoint.StartLine - 1]; } } } TreeNode op = new TreeNode(line); op.Tag = i; code.Nodes.Add(op); } } treeView2.ExpandAll(); }
protected abstract TType[] GetParameters (TMethod method);
protected abstract TType[] GetInterfaces (TType type); // may return interfaces from base classes as well. May return null if no interfaces found. protected abstract TMethod GetBaseMethod (TMethod method);
public ObjCMethod (Registrar registrar, ObjCType declaringType, TMethod method) : base (registrar, declaringType) { Method = method; }
public string ComputeSignature (TType DeclaringType, TMethod Method, ObjCMember member = null, bool isCategoryInstance = false) { var success = true; var signature = new StringBuilder (); bool is_ctor; var method = member as ObjCMethod; if (Method != null) { is_ctor = IsConstructor (Method); } else { is_ctor = method.IsConstructor; } if (is_ctor) { signature.Append ('@'); } else { var ReturnType = Method != null ? GetReturnType (Method) : method.ReturnType; signature.Append (ToSignature (ReturnType, member, ref success)); if (!success) throw CreateException (4104, Method, "The registrar cannot marshal the return value of type `{0}` in the method `{1}.{2}`.", GetTypeFullName (ReturnType), GetTypeFullName (DeclaringType), GetDescriptiveMethodName (Method)); } signature.Append ("@:"); TType[] parameters; if (Method != null) { parameters = GetParameters (Method); } else { parameters = method.Parameters; } if (parameters != null) { for (int i = 0; i < parameters.Length; i++) { if (i == 0 && isCategoryInstance) continue; var type = parameters [i]; if (IsByRef (type)) { signature.Append ("^"); signature.Append (ToSignature (GetElementType (type), member, ref success)); } else { signature.Append (ToSignature (type, member, ref success)); } if (!success) throw CreateException (4136, Method, "The registrar cannot marshal the parameter type '{0}' of the parameter '{1}' in the method '{2}.{3}'", GetTypeFullName (type), GetParameterName (Method, i), GetTypeFullName (DeclaringType), GetDescriptiveMethodName (Method)); } } return signature.ToString (); }
// This method is not thread-safe wrt 'types', and must be called with // a lock held on 'types'. ObjCType RegisterTypeUnsafe (TType type, ref List<Exception> exceptions) { ObjCType objcType; bool isGenericType = false; bool isProtocol = false; bool isInformalProtocol = false; if (IsGenericType (type)) { type = GetGenericTypeDefinition (type); isGenericType = true; } if (types.TryGetValue (type, out objcType)) { OnReloadType (objcType); return objcType; } var categoryAttribute = GetCategoryAttribute (type); if (categoryAttribute != null) return RegisterCategory (type, categoryAttribute, ref exceptions); if (!IsNSObject (type)) { //Trace ("{0} is not derived from NSObject", GetTypeFullName (type)); if (!IsInterface (type)) return null; if (!HasProtocolAttribute (type)) return null; if (isGenericType) { exceptions.Add (ErrorHelper.CreateError (4148, "The registrar found a generic protocol: '{0}'. Exporting generic protocols is not supported.", GetTypeFullName (type))); return null; } // This is a protocol var pAttr = GetProtocolAttribute (type); isInformalProtocol = pAttr.IsInformal; isProtocol = true; } // make sure the base type is already registered var baseType = GetBaseType (type); ObjCType baseObjCType = null; if (baseType != null) { Trace ("Registering base type {0} of {1}", GetTypeName (baseType), GetTypeName (type)); baseObjCType = RegisterTypeUnsafe (baseType, ref exceptions); } var register_attribute = GetRegisterAttribute (type); if (register_attribute != null && register_attribute.SkipRegistration) return baseObjCType; objcType = new ObjCType () { Registrar = this, RegisterAttribute = GetRegisterAttribute (type), Type = type, IsModel = HasModelAttribute (type), IsProtocol = isProtocol, IsGeneric = isGenericType, }; objcType.VerifyRegisterAttribute (); objcType.Protocols = GetProtocols (objcType, ref exceptions); objcType.BaseType = isProtocol ? null : (baseObjCType ?? objcType); objcType.IsWrapper = (isProtocol && !isInformalProtocol) ? (GetProtocolAttributeWrapperType (objcType.Type) != null) : (objcType.RegisterAttribute != null && objcType.RegisterAttribute.IsWrapper); if (!objcType.IsWrapper && objcType.BaseType != null) VerifyTypeInSDK (ref exceptions, objcType.BaseType.Type, baseTypeOf: objcType.Type); // make sure all the protocols this type implements are registered if (objcType.Protocols != null) { foreach (var p in objcType.Protocols) { Trace ("Registering implemented protocol {0} of {1}", p == null ? "null" : p.ProtocolName, GetTypeName (type)); OnRegisterProtocol (p); } } TType previous_type; if (objcType.IsProtocol) { lock (protocol_map) { if (protocol_map.TryGetValue (objcType.ExportedName, out previous_type)) throw ErrorHelper.CreateError (4126, "Cannot register two managed protocols ('{0}' and '{1}') with the same native name ('{2}').", GetAssemblyQualifiedName (type), GetAssemblyQualifiedName (previous_type), objcType.ExportedName); protocol_map.Add (objcType.ExportedName, type); } } else { lock (type_map) { if (type_map.TryGetValue (objcType.ExportedName, out previous_type)) throw ErrorHelper.CreateError (4118, "Cannot register two managed types ('{0}' and '{1}') with the same native name ('{2}').", GetAssemblyQualifiedName (type), GetAssemblyQualifiedName (previous_type), objcType.ExportedName); type_map.Add (objcType.ExportedName, type); } } types.Add (type, objcType); Trace (" [TYPE] Registering {0} => {1} IsWrapper: {2} BaseType: {3} IsModel: {4} IsProtocol: {5}", type.ToString ().Replace ('+', '/'), objcType.ExportedName, objcType.IsWrapper, objcType.BaseType == null ? "null" : objcType.BaseType.Name, objcType.IsModel, objcType.IsProtocol); // Special methods bool is_first_nonWrapper = false; var methods = new List<TMethod> (CollectMethods (type)); if (!isProtocol) { is_first_nonWrapper = !(objcType.IsWrapper || objcType.IsModel) && (objcType.BaseType.IsWrapper || objcType.BaseType.IsModel); if (is_first_nonWrapper) { bool isCalayerSubclass = IsSubClassOf (objcType.Type, CoreAnimation, "CALayer"); if (!isCalayerSubclass) { objcType.Add (new ObjCMethod (this, objcType, null) { Selector = "release", Trampoline = Trampoline.Release, Signature = "v@:", IsStatic = false, }, ref exceptions); objcType.Add (new ObjCMethod (this, objcType, null) { Selector = "retain", Trampoline = Trampoline.Retain, Signature = "@@:", IsStatic = false, }, ref exceptions); } objcType.Add (new ObjCMethod (this, objcType, null) { Selector = "xamarinGetGCHandle", Trampoline = Trampoline.GetGCHandle, Signature = "i@:", IsStatic = false, }, ref exceptions); objcType.Add (new ObjCMethod (this, objcType, null) { Selector = "xamarinSetGCHandle:", Trampoline = Trampoline.SetGCHandle, Signature = "v@:i", IsStatic = false, }, ref exceptions); } // Find conform_to_protocol if (conforms_to_protocol == null && Is (type, Foundation, "NSObject")) { foreach (var method in methods) { switch (GetMethodName (method)) { case "InvokeConformsToProtocol": invoke_conforms_to_protocol = method; break; case "ConformsToProtocol": conforms_to_protocol = method; break; } if (invoke_conforms_to_protocol != null && conforms_to_protocol != null) break; } } #if MMP || MTOUCH // Special fields if (is_first_nonWrapper) { // static registrar objcType.Add (new ObjCField () { DeclaringType = objcType, FieldType = "XamarinObject",// "^v", // void* Name = "__monoObjectGCHandle", }, ref exceptions); } #endif } var properties = new List<TProperty> (CollectProperties (type)); var hasProtocolMemberAttributes = false; if (isProtocol && !isInformalProtocol) { var attribs = GetProtocolMemberAttributes (type); foreach (var attrib in attribs) { hasProtocolMemberAttributes = true; if (attrib.IsProperty) { if (attrib.IsStatic) { // There is no such things as a static property in ObjC, so export this as just the getter[+setter]. var objcGetter = new ObjCMethod (this, objcType, null) { Name = attrib.Name, Selector = attrib.GetterSelector, Parameters = new TType[] { }, ReturnType = attrib.PropertyType, IsStatic = attrib.IsStatic, IsOptional = !attrib.IsRequired, IsConstructor = false, }; objcType.Add (objcGetter, ref exceptions); if (!string.IsNullOrEmpty (attrib.SetterSelector)) { var objcSetter = new ObjCMethod (this, objcType, null) { Name = attrib.Name, Selector = attrib.SetterSelector, Parameters = new TType[] { attrib.PropertyType }, ReturnType = GetSystemVoidType (), IsStatic = attrib.IsStatic, IsOptional = !attrib.IsRequired, IsConstructor = false, }; objcType.Add (objcSetter, ref exceptions); } } else { var objcProperty = new ObjCProperty () { Registrar = this, DeclaringType = objcType, Property = null, Name = attrib.Name, Selector = attrib.Selector, ArgumentSemantic = attrib.ArgumentSemantic, IsReadOnly = string.IsNullOrEmpty (attrib.SetterSelector), IsStatic = attrib.IsStatic, IsOptional = !attrib.IsRequired, GetterSelector = attrib.GetterSelector, SetterSelector = attrib.SetterSelector, PropertyType = attrib.PropertyType, }; objcType.Add (objcProperty, ref exceptions); } } else { var objcMethod = new ObjCMethod (this, objcType, null) { Name = attrib.Name, Selector = attrib.Selector, ArgumentSemantic = attrib.ArgumentSemantic, IsVariadic = attrib.IsVariadic, ReturnType = attrib.ReturnType ?? GetSystemVoidType (), IsStatic = attrib.IsStatic, IsOptional = !attrib.IsRequired, IsConstructor = false, }; if (attrib.ParameterType != null) { var parameters = new TType [attrib.ParameterType.Length]; for (int i = 0; i < parameters.Length; i++) { if (attrib.ParameterByRef [i]) { parameters [i] = MakeByRef (attrib.ParameterType [i]); } else { parameters [i] = attrib.ParameterType [i]; } } objcMethod.Parameters = parameters; } else { objcMethod.Parameters = new TType[] { }; } objcType.Add (objcMethod, ref exceptions); } } } foreach (TProperty property in properties) { if (hasProtocolMemberAttributes) continue; if (!isProtocol) { var ca = GetConnectAttribute (property); if (ca != null) { if (!IsINativeObject (GetPropertyType (property))) { AddException (ref exceptions, CreateException (4139, property, "The registrar cannot marshal the property type '{0}' of the property '{1}.{2}'. Properties with the [Connect] attribute must have a property type of NSObject (or a subclass of NSObject).", GetTypeFullName (GetPropertyType (property)), GetTypeFullName (type), GetPropertyName (property))); continue; } objcType.Add (new ObjCField () { DeclaringType = objcType, Name = ca.Name ?? GetPropertyName (property), #if !MTOUCH && !MMP Size = Is64Bits ? 8 : 4, Alignment = (byte) (Is64Bits ? 3 : 2), #endif FieldType = "@", IsProperty = true, }, ref exceptions); } } var ea = GetExportAttribute (property); if (ea == null) continue; if (IsStatic (property) && (objcType.IsWrapper || objcType.IsModel)) { // This is useless to export, since the user can't actually do anything with it, // it'll just call back into the base implementation. continue; } if (IsStatic (property) && isGenericType) { AddException (ref exceptions, CreateException (4131, property, "The registrar cannot export static properties in generic classes ('{0}.{1}').", GetTypeFullName (type), GetPropertyName (property))); continue; } TType property_type = null; if (isGenericType && !VerifyIsConstrainedToNSObject (GetPropertyType (property), out property_type)) { AddException (ref exceptions, CreateException (4132, property, "The registrar found an invalid generic return type '{0}' in the property '{1}.{2}'. The return type must have an 'NSObject' constraint.", GetTypeFullName (GetPropertyType (property)), GetTypeFullName (type), GetPropertyName (property))); continue; } if (property_type == null) property_type = GetPropertyType (property); Trace (" [PROPERTY] {0} => {1}", property, ea.Selector); var objcProperty = new ObjCProperty () { Registrar = this, DeclaringType = objcType, Property = property, Name = property.Name, Selector = ea.Selector ?? GetPropertyName (property), ArgumentSemantic = ea.ArgumentSemantic, PropertyType = property_type, }; TMethod getter = GetGetMethod (property); TMethod setter = GetSetMethod (property); if (getter != null && VerifyNonGenericMethod (ref exceptions, type, getter)) { var method = new ObjCMethod (this, objcType, getter) { Selector = ea.Selector ?? GetPropertyName (property), ArgumentSemantic = ea.ArgumentSemantic, ReturnType = property_type, }; List<Exception> excs = null; if (!method.ValidateSignature (ref excs)) { exceptions.Add (CreateException (4138, excs [0], property, "The registrar cannot marshal the property type '{0}' of the property '{1}.{2}'.", GetTypeFullName (property.PropertyType), property.DeclaringType.FullName, property.Name)); continue; } if (!objcType.Add (method, ref exceptions)) continue; Trace (" [GET] {0}", objcType.Methods [objcType.Methods.Count - 1].Name); } if (setter != null && VerifyNonGenericMethod (ref exceptions, type, setter)) { string setterName = ea.Selector ?? GetPropertyName (property); var method = new ObjCMethod (this, objcType, setter) { Selector = CreateSetterSelector (setterName), ArgumentSemantic = ea.ArgumentSemantic, Parameters = new TType[] { property_type }, }; List<Exception> excs = null; if (!method.ValidateSignature (ref excs)) { exceptions.Add (CreateException (4138, excs [0], property, "The registrar cannot marshal the property type '{0}' of the property '{1}.{2}'.", GetTypeFullName (property.PropertyType), property.DeclaringType.FullName, property.Name)); continue; } if (!objcType.Add (method, ref exceptions)) continue; Trace (" [SET] {0}", objcType.Methods [objcType.Methods.Count - 1].Name); } objcType.Add (objcProperty, ref exceptions); } var custom_conforms_to_protocol = !is_first_nonWrapper; // we only have to generate the conformsToProtocol method for the first non-wrapper type. #if MONOMAC ObjCMethod custom_copy_with_zone = null; var isNSCellSubclass = IsSubClassOf (type, AppKit, "NSCell"); #endif Dictionary<TMethod, List<TMethod>> method_map = null; if (!isProtocol) method_map = PrepareMethodMapping (type); foreach (TMethod method in methods) { if (hasProtocolMemberAttributes) continue; var ea = GetExportAttribute (method); if (ea == null) { List<TMethod> impls; if (method_map != null && method_map.TryGetValue (method, out impls)) { if (impls.Count != 1) { AddException (ref exceptions, Shared.GetMT4127 (method, impls)); continue; } ea = GetExportAttribute (impls [0]); } } if (ea == null) continue; if (IsStatic (method) && (objcType.IsWrapper || objcType.IsModel) && !(objcType.IsProtocol && !objcType.IsFakeProtocol)) { // This is useless to export, since the user can't actually do anything with it, // it'll just call back into the base implementation. continue; } if (objcType.IsModel && IsVirtual (method)) continue; Trace (" [METHOD] {0} => {1}", method, ea.Selector); if (!custom_conforms_to_protocol && method.DeclaringType == type && GetBaseMethod (method) == conforms_to_protocol) custom_conforms_to_protocol = true; if (!VerifyNonGenericMethod (ref exceptions, type, method)) continue; var objcMethod = new ObjCMethod (this, objcType, method); if (!objcMethod.SetExportAttribute (ea, ref exceptions)) continue; #if MONOMAC if (objcMethod.Selector == "copyWithZone:") custom_copy_with_zone = objcMethod; #endif if (IsStatic (method) && isGenericType) { AddException (ref exceptions, CreateException (4130, method, "The registrar cannot export static methods in generic classes ('{0}').", GetDescriptiveMethodName (type, method))); continue; } else if (isGenericType && !VerifyIsConstrainedToNSObject (ref exceptions, type, objcMethod)) { continue; } try { objcType.Add (objcMethod, ref exceptions); } catch (Exception ex) { AddException (ref exceptions, ex); } } if (!isProtocol && !custom_conforms_to_protocol) { objcType.Add (new ObjCMethod (this, objcType, invoke_conforms_to_protocol) { Selector = "conformsToProtocol:", Trampoline = Trampoline.Normal, Signature = "B@:^v", IsStatic = false, }, ref exceptions); } #if MONOMAC if (isNSCellSubclass) { if (custom_copy_with_zone != null) { custom_copy_with_zone.Trampoline = Trampoline.CopyWithZone2; } else { objcType.Add (new ObjCMethod (this, objcType, null) { Selector = "copyWithZone:", Trampoline = Trampoline.CopyWithZone1, Signature = "@@:^v", IsStatic = false, }, ref exceptions); } } #endif foreach (TMethod ctor in CollectConstructors (type)) { if (IsStatic (ctor)) continue; var parameters = GetParameters (ctor); if (parameters == null || parameters.Length == 0) { Trace (" [CTOR] {0} default => init", GetTypeName (type)); objcType.Add (new ObjCMethod (this, objcType, ctor) { Selector = "init", Trampoline = Trampoline.Constructor, }, ref exceptions); continue; } var ea = GetExportAttribute (ctor); if (ea == null) continue; Trace (" [CTOR] {2} {0} => {1}", GetMethodName (ctor), ea.Selector, GetTypeName (type)); if (!VerifyNonGenericMethod (ref exceptions, type, ctor)) continue; var method = new ObjCMethod (this, objcType, ctor) { Trampoline = Trampoline.Constructor, }; if (method.SetExportAttribute (ea, ref exceptions)) objcType.Add (method, ref exceptions); } if (objcType.IsProtocol) { OnRegisterProtocol (objcType); } else { OnRegisterType (objcType); } return objcType; }
public static void Inject(string input_assembly_path, string output_assembly_path, string logger_assembly_path, string logger_type_name, string before_call_log_method_name, string log_attribute_name) { System.Diagnostics.Debug.Assert(System.IO.File.Exists(input_assembly_path)); if (input_assembly_path != output_assembly_path) { if (System.IO.File.Exists(output_assembly_path)) { System.IO.File.Delete(output_assembly_path); } System.IO.File.Copy(input_assembly_path, output_assembly_path); System.Diagnostics.Debug.Assert(System.IO.File.Exists(output_assembly_path)); } var assembly_resolver = new Mono.Cecil.DefaultAssemblyResolver(); string input_assembly_directory = System.IO.Path.GetDirectoryName(input_assembly_path); assembly_resolver.AddSearchDirectory(input_assembly_directory); #if SILVERLIGHT Microsoft.Silverlight.Build.Tasks.GetSilverlightFrameworkPath path_task = new Microsoft.Silverlight.Build.Tasks.GetSilverlightFrameworkPath(); path_task.RegistryBase = "Software\\Microsoft\\Microsoft SDKs\\Silverlight"; path_task.Execute(); assembly_resolver.AddSearchDirectory(path_task.SilverlightPath); foreach (string path in path_task.SilverlightSDKPaths) { assembly_resolver.AddSearchDirectory(path); } #endif Mono.Cecil.AssemblyDefinition injectible_assembly = Mono.Cecil.AssemblyDefinition.ReadAssembly(output_assembly_path, new Mono.Cecil.ReaderParameters { AssemblyResolver = assembly_resolver }); System.Diagnostics.Debug.Assert(System.IO.File.Exists(logger_assembly_path)); Mono.Cecil.AssemblyDefinition logger_assembly = Mono.Cecil.AssemblyDefinition.ReadAssembly(logger_assembly_path); Mono.Cecil.TypeDefinition logger_type = logger_assembly.MainModule.GetType(logger_type_name); System.Diagnostics.Debug.Assert(logger_type != null); Mono.Cecil.MethodDefinition before_callback_method_info = logger_type.Methods.First(m => m.Name == before_call_log_method_name); Mono.Cecil.MethodReference before_callback_reference = injectible_assembly.MainModule.Import(before_callback_method_info); //make sure to get System.Object.ToString method from assembly compatible with the injected assembly #if SILVERLIGHT string core_assembly_path = path_task.SilverlightPath + "mscorlib.dll"; Mono.Cecil.AssemblyDefinition core_assembly = Mono.Cecil.AssemblyDefinition.ReadAssembly(core_assembly_path); Mono.Cecil.TypeDefinition object_type = core_assembly.MainModule.GetType("System.Object"); Mono.Cecil.MethodDefinition to_string_method_info = object_type.Methods.First(m => m.Name == "ToString"); #else System.Reflection.MethodInfo to_string_method_info = typeof(System.Object).GetMethod("ToString"); #endif Mono.Cecil.MethodReference to_string_reference = injectible_assembly.MainModule.Import(to_string_method_info); foreach (Mono.Cecil.TypeDefinition type_definition in injectible_assembly.MainModule.Types) { bool is_type_logable = type_definition.CustomAttributes.Any(a => a.AttributeType.FullName == log_attribute_name); foreach (Mono.Cecil.MethodDefinition method_definition in type_definition.Methods) { bool is_method_logable = is_type_logable || method_definition.CustomAttributes.Any(a => a.AttributeType.FullName == log_attribute_name); if (is_method_logable) { Mono.Cecil.Cil.ILProcessor processor = method_definition.Body.GetILProcessor(); System.Collections.Generic.List <Mono.Cecil.Cil.Instruction> original_instructions = new System.Collections.Generic.List <Mono.Cecil.Cil.Instruction>(); original_instructions.AddRange(method_definition.Body.Instructions); method_definition.Body.Instructions.Clear(); #region parameters int method_parameters_count = method_definition.Parameters.Count; int local_variables_count = method_definition.Body.Variables.Count; int arguments_array_index = local_variables_count; // Create an array of type System.String with the same number of elements as count of method parameters // Add metadata for a new variable of type System.String[] to method body // .locals init (System.String[] V_0) Mono.Cecil.ArrayType arguments = new Mono.Cecil.ArrayType(injectible_assembly.MainModule.TypeSystem.String); method_definition.Body.Variables.Add(new Mono.Cecil.Cil.VariableDefinition((Mono.Cecil.TypeReference)arguments)); method_definition.Body.InitLocals = true; method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldc_I4, method_parameters_count)); method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Newarr, injectible_assembly.MainModule.TypeSystem.String)); // This instruction will store the address of the newly created array in the newly added local variable, which is at index = local_variables_count method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Stloc, arguments_array_index)); #region parameters_to_string // Instance methods have an an implicit argument called "this" // so in that case we need to refer to actual arguments with +1 position int parameter_offset = method_definition.IsStatic ? 0 : 1; for (int i = 0; i < method_parameters_count; ++i) { // load argument array and current index method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldloc, arguments_array_index)); method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldc_I4, i)); // load argument method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldarga, i + parameter_offset)); // convert argument to string Mono.Cecil.TypeReference argument_type = method_definition.Parameters[i].ParameterType; method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Constrained, argument_type)); method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Callvirt, to_string_reference)); // store string in array method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Stelem_Ref)); } #endregion parameters_to_string string method_signature = method_definition.ToString(); // load method signature method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldstr, method_signature)); // load parameters array method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldloc, arguments_array_index)); #endregion parameters // load before call instruction method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Call, before_callback_reference)); foreach (var IL in original_instructions) { method_definition.Body.Instructions.Add(IL); } } } } injectible_assembly.Write(output_assembly_path); }
//public IMethod GetMethod(string funcname, MethodParamList types) //{ // if (type_CLRSharp.HasMethods) // { // foreach (var m in type_CLRSharp.Methods) // { // if (m.Name != funcname) continue; // if ((types == null) ? !m.HasParameters : (m.Parameters.Count == types.Count)) // { // bool match = true; // for (int i = 0; i < ((types == null) ? 0 : types.Count); i++) // { // var envtype = env.GetType(m.Parameters[i].ParameterType.FullName); // if (envtype.IsEnum()) // { // if (envtype.TypeForSystem != types[i].TypeForSystem) // { // match = false; // break; // } // } // else // { // if (envtype != types[i]) // { // match = false; // break; // } // } // } // if (match) // return new Method_Common_CLRSharp(this, m); // } // } // } // return null; //} public IMethod GetMethodOverloaded(string funcname, MethodParamList types) { Mono.Cecil.MethodDefinition minDistanceMethod = null; List <int> minDistanceParameters = null; if (type_CLRSharp.HasMethods) { foreach (var m in type_CLRSharp.Methods) { if (m.Name != funcname) { continue; } if ((types == null) ? !m.HasParameters : (m.Parameters.Count == types.Count)) { bool match = true; List <int> currentDistanceParameters = new List <int>(); for (int i = 0; i < ((types == null) ? 0 : types.Count); i++) { var envtype = env.GetType(m.Parameters[i].ParameterType.FullName); if (envtype.IsEnum()) { if (envtype.TypeForSystem != types[i].TypeForSystem) { match = false; break; } } else { if (!(envtype.TypeForSystem.IsAssignableFrom(types[i].TypeForSystem))) { match = false; break; } currentDistanceParameters.Add(GetInheritanceDistance(envtype.TypeForSystem, types[i].TypeForSystem)); } } if (match) { if (minDistanceParameters == null) { minDistanceMethod = m; minDistanceParameters = currentDistanceParameters; } else { for (int i = 0; i < currentDistanceParameters.Count; i++) { if (currentDistanceParameters[i] < minDistanceParameters[i]) { minDistanceMethod = m; minDistanceParameters = currentDistanceParameters; } } } } } } if (minDistanceMethod == null) { return(null); } return(new Method_Common_CLRSharp(this, minDistanceMethod)); } return(null); }
protected abstract string GetParameterName (TMethod method, int parameter_index);
public MethodEntry(Mono.Cecil.MethodDefinition mdef) { m_mdef = mdef; }
protected abstract bool IsVirtual (TMethod method);
/// <summary> /// Aspect method to use for method call substition /// </summary> /// <param name="typeBuilder"></param> /// <param name="il"></param> /// <param name="method"></param> /// <param name="replaceMethod">Replace Method</param> /// <returns></returns> internal bool MethodCall(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.Cil.ILProcessor il, Mono.Cecil.MethodDefinition method, Mono.Cecil.MethodDefinition replaceMethod) { if (!replaceMethod.IsStatic) { return(false); } var attrs = method.GetCustomAttributes <StaticMethodReplacerAttribute>(); MethodInfo meth = null; foreach (var attr in attrs) { var staticType = attr.staticMethodType; var smeth = staticType.GetMethod(replaceMethod.Name, BindingFlags.Static | BindingFlags.Public); if (smeth != null) { meth = smeth; } } if (meth == null) { return(false); } il.Emit(Mono.Cecil.Cil.OpCodes.Call, meth); return(true); }
protected abstract bool IsStatic (TMethod method);
public static ProductException CreateError(Application app, int code, Mono.Cecil.MethodDefinition location, Instruction instruction, string message, params object [] args) { return(Create(app, code, true, null, location, instruction, message, args)); }
protected abstract bool HasThisAttribute (TMethod method);
/// <summary> /// Add the given method to its declaring class. /// </summary> protected override void SetAccessFlags(DexLib.MethodDefinition dmethod, MethodDefinition method) { base.SetAccessFlags(dmethod, method); dmethod.IsNative = true; }
protected abstract bool IsConstructor (TMethod method);
bool VerifyNonGenericMethod (ref List<Exception> exceptions, TType declaringType, TMethod method) { if (!IsGenericMethod (method)) return true; AddException (ref exceptions, CreateException (4113, method, "The registrar found a generic method: '{0}'. Exporting generic methods is not supported, and will lead to random behavior and/or crashes", GetDescriptiveMethodName (declaringType, method))); return false; }
protected abstract TType GetReturnType (TMethod method);
/// <summary> /// Aspect method to use for method call substition /// </summary> /// <param name="typeBuilder"></param> /// <param name="il"></param> /// <param name="method"></param> /// <param name="replaceMethod">Replace Method</param> /// <returns></returns> internal bool MethodCall(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.Cil.ILProcessor il, Mono.Cecil.MethodDefinition method, Mono.Cecil.MethodDefinition replaceMethod) { var methodName = method.Name.Replace("~", string.Empty); var isRecursive = methodName == replaceMethod.Name; var declaringType = replaceMethod.DeclaringType; var methodCall = replaceMethod; if (isRecursive) { methodCall = typeBuilder.GetMethodEx(methodCall.Name, methodCall.ReturnType, methodCall.Parameters.Select(x => x.ParameterType).ToArray()); il.Emit(Mono.Cecil.Cil.OpCodes.Tail); } il.Emit(declaringType.IsValueType || replaceMethod.IsStatic || methodCall.ReturnType.IsValueType ? Mono.Cecil.Cil.OpCodes.Call : Mono.Cecil.Cil.OpCodes.Callvirt, methodCall); il.Emit(Mono.Cecil.Cil.OpCodes.Ret); return(true); }
protected abstract ExportAttribute GetExportAttribute (TProperty property); // Return null if no attribute is found. Must check the base property (i.e. if property is overriding a property in a base class, must check the overridden property for the attribute). protected abstract ExportAttribute GetExportAttribute (TMethod method); // Return null if no attribute is found. Must check the base method (i.e. if method is overriding a method in a base class, must check the overridden method for the attribute).
public ILMethod(ILType type, Mono.Cecil.MethodDefinition method, ILogger logger = null) { this.method = method; if (method != null) { returntype = method.ReturnType.FullName; if (method.HasParameters) { hasParam = true; foreach (var p in method.Parameters) { string paramtype = p.ParameterType.FullName; try { var _type = p.ParameterType.Resolve(); foreach (var i in _type.Interfaces) { if (i.InterfaceType.Name == "IApiInterface") { paramtype = "IInteropInterface"; } } } catch { } this.paramtypes.Add(new NeoParam(p.Name, paramtype)); } } if (method.HasBody) { var bodyNative = method.Body; if (bodyNative.HasVariables) { foreach (var v in bodyNative.Variables) { var indexname = v.VariableType.Name + ":" + v.Index; this.body_Variables.Add(new NeoParam(indexname, v.VariableType.FullName)); } } for (int i = 0; i < bodyNative.Instructions.Count; i++) { var code = bodyNative.Instructions[i]; OpCode c = new OpCode { code = (CodeEx)(int)code.OpCode.Code, addr = code.Offset }; var sp = method.DebugInformation.GetSequencePoint(code); if (sp != null) { c.debugcode = sp.Document.Url; c.debugline = sp.StartLine; } c.InitToken(code.Operand); this.body_Codes.Add(c.addr, c); } } } }
protected abstract TType GetProtocolAttributeWrapperType (TType type); // Return null if no attribute is found. Do not consider base types. protected abstract bool HasReleaseAttribute (TMethod method); // Returns true of the method's return type/value has a [Release] attribute.
public ILMethod(ILType type, Mono.Cecil.MethodDefinition method, ILogger logger = null) { this.type = type; this.method = method; if (method != null) { returntype = method.ReturnType.FullName; if (method.HasParameters) { hasParam = true; foreach (var p in method.Parameters) { string paramtype = p.ParameterType.FullName; try { var _type = p.ParameterType.Resolve(); foreach (var i in _type.Interfaces) { if (i.InterfaceType.Name == "IApiInterface") { paramtype = "IInteropInterface"; } } } catch { } this.paramtypes.Add(new NeoParam(p.Name, paramtype)); } } if (method.HasBody) { var bodyNative = method.Body; if (bodyNative.HasVariables) { foreach (var v in bodyNative.Variables) { var indexname = v.VariableType.Name + ":" + v.Index; this.body_Variables.Add(new NeoParam(indexname, v.VariableType.FullName)); } } for (int i = 0; i < bodyNative.Instructions.Count; i++) { var code = bodyNative.Instructions[i]; OpCode c = new OpCode { code = (CodeEx)(int)code.OpCode.Code, addr = code.Offset }; var sp = method.DebugInformation.GetSequencePoint(code); if (sp != null) { c.debugcode = sp.Document.Url; c.debugline = sp.StartLine; } c.InitToken(code.Operand); this.body_Codes.Add(c.addr, c); } if (method.Body.HasExceptionHandlers) { var mapTryInfos = new Dictionary <string, ILTryInfo>(); foreach (var e in method.Body.ExceptionHandlers) { if (e.HandlerType == Mono.Cecil.Cil.ExceptionHandlerType.Catch) { var key = e.TryStart.Offset + "_" + e.TryEnd.Offset; if (mapTryInfos.ContainsKey(key) == false) { mapTryInfos[key] = new ILTryInfo(); } var tryinfo = mapTryInfos[key]; tryinfo.addr_Try_Begin = e.TryStart.Offset; tryinfo.addr_Try_End = e.TryEnd.Offset; var catchtypestr = e.CatchType.FullName; tryinfo.catch_Infos[catchtypestr] = new ILCatchInfo() { addrBegin = e.HandlerStart.Offset, addrEnd = e.HandlerEnd.Offset, catchType = catchtypestr }; } else if (e.HandlerType == Mono.Cecil.Cil.ExceptionHandlerType.Finally) { int start = e.TryStart.Offset; int end = e.TryEnd.Offset; Mono.Cecil.Cil.ExceptionHandler handler = null; foreach (var tryinfocatch in method.Body.ExceptionHandlers) { if (tryinfocatch.HandlerType == Mono.Cecil.Cil.ExceptionHandlerType.Catch && tryinfocatch.TryStart.Offset == e.TryStart.Offset && tryinfocatch.TryEnd.Offset <= e.TryEnd.Offset) {//find include catch element. if (handler == null) { handler = tryinfocatch; } else if (handler.TryEnd.Offset < tryinfocatch.TryEnd.Offset) { handler = tryinfocatch; } } } if (handler != null) { start = handler.TryStart.Offset; end = handler.TryEnd.Offset; } var key = start + "_" + end; if (mapTryInfos.ContainsKey(key) == false) { mapTryInfos[key] = new ILTryInfo(); } var tryinfo = mapTryInfos[key]; tryinfo.addr_Try_Begin = start; tryinfo.addr_Try_End = end; tryinfo.addr_Try_End_F = e.TryEnd.Offset; tryinfo.addr_Finally_Begin = e.HandlerStart.Offset; tryinfo.addr_Finally_End = e.HandlerEnd.Offset; } else { throw new Exception("not support yet." + e.HandlerType); } } this.tryInfos = new List <ILTryInfo>(mapTryInfos.Values); foreach (var info in this.tryInfos) { if (this.tryPositions.Contains(info.addr_Try_Begin) == false) { this.tryPositions.Add(info.addr_Try_Begin); } } } } } }
protected abstract bool IsGenericMethod (TMethod method);
protected abstract Exception CreateException (int code, Exception innerException, TMethod method, string message, params object[] args);
protected abstract string GetMethodName (TMethod method);
private bool TryInsertMethod(NeoModule outModule, Mono.Cecil.MethodDefinition method) { var oldaddr = this.addr; var oldaddrconv = new Dictionary <int, int>(); foreach (int k in addrconv.Keys) { oldaddrconv[k] = addrconv[k]; } var typename = method.DeclaringType.FullName; ILType type; if (inModule.mapType.TryGetValue(typename, out type) == false) { type = new ILType(null, method.DeclaringType); inModule.mapType[typename] = type; } var _method = type.methods[method.FullName]; try { NeoMethod nm = new NeoMethod(); if (method.FullName.Contains(".cctor")) { CctorSubVM.Parse(_method, this.outModule); //continue; return(false); } if (method.IsConstructor) { return(false); //continue; } nm._namespace = method.DeclaringType.FullName; nm.name = method.FullName; nm.displayName = method.Name; Mono.Collections.Generic.Collection <Mono.Cecil.CustomAttribute> ca = method.CustomAttributes; foreach (var attr in ca) { if (attr.AttributeType.Name == "DisplayNameAttribute") { nm.displayName = (string)attr.ConstructorArguments[0].Value; } } nm.inSmartContract = method.DeclaringType.BaseType.Name == "SmartContract"; nm.isPublic = method.IsPublic; this.methodLink[_method] = nm; outModule.mapMethods[nm.name] = nm; ConvertMethod(_method, nm); return(true); } catch { return(false); } finally { this.addr = oldaddr; this.addrconv.Clear(); foreach (int k in oldaddrconv.Keys) { addrconv[k] = oldaddrconv[k]; } } }
protected Exception CreateException (int code, TMethod method, string message, params object[] args) { return CreateException (code, null, method, message, args); }
//以后准备用自定义Body采集一遍,可以先过滤处理掉Mono.Cecil的代码中的指向,执行会更快 public CodeBody(CLRSharp.ICLRSharp_Environment env, Mono.Cecil.MethodDefinition _def) { this.method = _def; Init(env); }
protected string GetDescriptiveMethodName (TMethod method) { if (method == null) return string.Empty; var sb = new StringBuilder (); sb.Append (GetMethodName (method)); sb.Append ("("); var pars = GetParameters (method); if (pars != null && pars.Length > 0) { for (int i = 0; i < pars.Length; i++) { if (i > 0) sb.Append (","); sb.Append (GetTypeFullName (pars [i])); } } sb.Append (")"); return sb.ToString (); }
public static ProductException Create(Application app, int code, bool error, Exception innerException, Mono.Cecil.MethodDefinition location, Instruction instruction, string message, params object [] args) { var e = new ProductException(code, error, innerException, message, args); if (location != null) { SetLocation(app, e, location, instruction); } return(e); }
string GetDescriptiveMethodName (TType type, TMethod method) { return GetTypeFullName (type) + "." + GetDescriptiveMethodName (method); }
/// <summary> /// Aspect code to inject at the beginning of weaved method /// </summary> /// <param name="typeBuilder">Type Builder</param> /// <param name="method">Method</param> /// <param name="parameter">Parameter</param> /// <param name="il">ILGenerator</param> internal void BeginBlock(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.MethodDefinition method, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.Cil.ILProcessor il) { }
/// <summary> /// Add the given method to its declaring class. /// </summary> protected override void SetAccessFlags(DexLib.MethodDefinition dmethod, MethodDefinition method) { dmethod.IsStatic = true; dmethod.IsPublic = true; }
private int _ConvertCall(OpCode src, AntsMethod to) { Mono.Cecil.MethodReference refs = src.tokenUnknown as Mono.Cecil.MethodReference; int calltype = 0; string callname = ""; byte[] callhash = null; VM.OpCode callcode = VM.OpCode.NOP; Mono.Cecil.MethodDefinition defs = null; try { defs = refs.Resolve(); } catch { } if (IsNonCall(defs)) { return(0); } else if (IsNotifyCall(defs, refs, to, out callname)) { calltype = 5; } else if (IsOpCall(defs, out callname)) { if (System.Enum.TryParse <VM.OpCode>(callname, out callcode)) { calltype = 2; } else { throw new Exception("Can not find OpCall:" + callname); } } else if (IsSysCall(defs, out callname)) { calltype = 3; } else if (IsAppCall(defs, out callhash)) { calltype = 4; } else if (this.outModule.mapMethods.ContainsKey(src.tokenMethod)) {//this is a call calltype = 1; } else {//maybe a syscall // or other if (src.tokenMethod.Contains("::op_Explicit(") || src.tokenMethod.Contains("::op_Implicit(")) { //各类显示隐示转换都忽略 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Int32 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)") { //donothing return(0); } else if (src.tokenMethod == "System.Int64 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)") { //donothing return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int32)")//int->bignumber { //donothing return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int64)") { return(0); } return(0); } else if (src.tokenMethod == "System.Void System.Diagnostics.Debugger::Break()") { _Convert1by1(VM.OpCode.NOP, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Equality(") || src.tokenMethod.Contains("::Equals(")) { var _ref = src.tokenUnknown as Mono.Cecil.MethodReference; if (_ref.DeclaringType.FullName == "System.Boolean" || _ref.DeclaringType.FullName == "System.Int32" || _ref.DeclaringType.FullName == "System.Numerics.BigInteger") { _Convert1by1(VM.OpCode.NUMEQUAL, src, to); } else { _Convert1by1(VM.OpCode.EQUAL, src, to); } //各类==指令 //有可能有一些会特殊处理,故还保留独立判断 //if (src.tokenMethod == "System.Boolean System.String::op_Equality(System.String,System.String)") //{ // _Convert1by1(VM.OpCode.EQUAL, src, to); // return 0; //} //else if (src.tokenMethod == "System.Boolean System.Object::Equals(System.Object)") //{ // _Convert1by1(VM.OpCode.EQUAL, src, to); // return 0; //} //_Convert1by1(VM.OpCode.EQUAL, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Inequality(")) { var _ref = src.tokenUnknown as Mono.Cecil.MethodReference; if (_ref.DeclaringType.FullName == "System.Boolean" || _ref.DeclaringType.FullName == "System.Int32" || _ref.DeclaringType.FullName == "System.Numerics.BigInteger") { _Convert1by1(VM.OpCode.NUMNOTEQUAL, src, to); } else { _Convert1by1(VM.OpCode.INVERT, src, to); _Insert1(VM.OpCode.EQUAL, "", to); } ////各类!=指令 ////有可能有一些会特殊处理,故还保留独立判断 //if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_Inequality(System.Numerics.BigInteger,System.Numerics.BigInteger)") //{ // _Convert1by1(VM.OpCode.INVERT, src, to); // _Insert1(VM.OpCode.EQUAL, "", to); // return 0; //} //_Convert1by1(VM.OpCode.INVERT, src, to); //_Insert1(VM.OpCode.EQUAL, "", to); return(0); } else if (src.tokenMethod.Contains("::op_Addition(")) { //各类+指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Addition(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.ADD, src, to); return(0); } _Convert1by1(VM.OpCode.ADD, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Subtraction(")) { //各类-指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Subtraction(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.SUB, src, to); return(0); } _Convert1by1(VM.OpCode.SUB, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Multiply(")) { //各类*指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Multiply(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.MUL, src, to); return(0); } _Convert1by1(VM.OpCode.MUL, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Division(")) { //各类/指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Division(System.Numerics.BigInteger, System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.DIV, src, to); return(0); } _Convert1by1(VM.OpCode.DIV, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Modulus(")) { //各类%指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Modulus(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.MOD, src, to); return(0); } _Convert1by1(VM.OpCode.MOD, src, to); return(0); } else if (src.tokenMethod.Contains("::op_LessThan(")) { //各类<指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(VM.OpCode.LT, src, to); return(0); } else if (src.tokenMethod.Contains("::op_GreaterThan(")) { //各类>指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(VM.OpCode.GT, src, to); return(0); } else if (src.tokenMethod.Contains("::op_LessThanOrEqual(")) { //各类<=指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(VM.OpCode.LTE, src, to); return(0); } else if (src.tokenMethod.Contains("::op_GreaterThanOrEqual(")) { //各类>=指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(VM.OpCode.GTE, src, to); return(0); } else if (src.tokenMethod.Contains("::get_Length(")) { //各类.Length指令 //"System.Int32 System.String::get_Length()" _Convert1by1(VM.OpCode.SIZE, src, to); return(0); } else if (src.tokenMethod.Contains("::Concat(")) { //各类.Concat //"System.String System.String::Concat(System.String,System.String)" _Convert1by1(VM.OpCode.CAT, src, to); return(0); } else if (src.tokenMethod == "System.String System.String::Substring(System.Int32,System.Int32)") { _Convert1by1(VM.OpCode.SUBSTR, src, to); return(0); } else if (src.tokenMethod == "System.Char System.String::get_Chars(System.Int32)") { _ConvertPush(1, src, to); _Convert1by1(VM.OpCode.SUBSTR, null, to); return(0); } else if (src.tokenMethod == "System.String System.String::Substring(System.Int32)") { throw new Exception("antsmachine cant use this call,please use .SubString(1,2) with 2 params."); } else if (src.tokenMethod == "System.String System.Char::ToString()") { return(0); } else if (src.tokenMethod == "System.Byte[] System.Numerics.BigInteger::ToByteArray()") { return(0); } else if (src.tokenMethod == "System.Void System.Numerics.BigInteger::.ctor(System.Byte[])") { _Convert1by1(VM.OpCode.DUPFROMALTSTACK, src, to); _ConvertPush(2, null, to); _Convert1by1(VM.OpCode.ROLL, null, to); _ConvertPush(2, null, to); _Convert1by1(VM.OpCode.ROLL, null, to); _Convert1by1(VM.OpCode.SETITEM, null, to); return(0); } else if (src.tokenMethod == "System.UInt32 <PrivateImplementationDetails>::ComputeStringHash(System.String)") { throw new Exception("需要neo.vm nuget更新以后,这个才可以放开,就可以处理 string switch了。"); //_Convert1by1(VM.OpCode.CSHARPSTRHASH32, src, to); //return 0; } else { } } if (calltype == 0) { throw new Exception("unknown call: " + src.tokenMethod + "\r\n in: " + to.name + "\r\n"); } var md = src.tokenUnknown as Mono.Cecil.MethodReference; var pcount = md.Parameters.Count; bool havethis = md.HasThis; if (calltype == 2) { //opcode call } else {//翻转参数顺序 //如果是syscall 并且有this的,翻转范围加一 if (calltype == 3 && havethis) { pcount++; } _Convert1by1(VM.OpCode.NOP, src, to); if (pcount <= 1) { } else if (pcount == 2) { _Insert1(VM.OpCode.SWAP, "swap 2 param", to); } else if (pcount == 3) { _InsertPush(2, "swap 0 and 2 param", to); _Insert1(VM.OpCode.XSWAP, "", to); } else { for (var i = 0; i < pcount / 2; i++) { int saveto = (pcount - 1 - i); _InsertPush(saveto, "load" + saveto, to); _Insert1(VM.OpCode.PICK, "", to); _InsertPush(i + 1, "load" + i + 1, to); _Insert1(VM.OpCode.PICK, "", to); _InsertPush(saveto + 2, "save to" + saveto + 2, to); _Insert1(VM.OpCode.XSWAP, "", to); _Insert1(VM.OpCode.DROP, "", to); _InsertPush(i + 1, "save to" + i + 1, to); _Insert1(VM.OpCode.XSWAP, "", to); _Insert1(VM.OpCode.DROP, "", to); } } } if (calltype == 1) { var c = _Convert1by1(VM.OpCode.CALL, null, to, new byte[] { 5, 0 }); c.needfixfunc = true; c.srcfunc = src.tokenMethod; return(0); } else if (calltype == 2) { _Convert1by1(callcode, null, to); return(0); } else if (calltype == 3) { var bytes = Encoding.UTF8.GetBytes(callname); if (bytes.Length > 252) { throw new Exception("string is to long"); } byte[] outbytes = new byte[bytes.Length + 1]; outbytes[0] = (byte)bytes.Length; Array.Copy(bytes, 0, outbytes, 1, bytes.Length); //bytes.Prepend 函数在 dotnet framework 4.6 编译不过 _Convert1by1(VM.OpCode.SYSCALL, null, to, outbytes); return(0); } else if (calltype == 4) { _Convert1by1(VM.OpCode.APPCALL, null, to, callhash); } else if (calltype == 5) { //把name参数推进去 var callp = Encoding.UTF8.GetBytes(callname); _ConvertPush(callp, src, to); //参数打包成array _ConvertPush(pcount + 1, null, to); _Convert1by1(VM.OpCode.PACK, null, to); //a syscall { var bytes = Encoding.UTF8.GetBytes("Neo.Runtime.Notify"); byte[] outbytes = new byte[bytes.Length + 1]; outbytes[0] = (byte)bytes.Length; Array.Copy(bytes, 0, outbytes, 1, bytes.Length); //bytes.Prepend 函数在 dotnet framework 4.6 编译不过 _Convert1by1(VM.OpCode.SYSCALL, null, to, outbytes); } } return(0); }
public static ProductException CreateWarning(Application app, int code, Exception innerException, Mono.Cecil.MethodDefinition location, string message, params object[] args) { return(Create(app, code, false, innerException, location, message, args)); }
/// <summary> /// Default ctor /// </summary> public DllImportMethodBuilder(AssemblyCompiler compiler, MethodDefinition method, string dllName) : base(compiler, method) { this.dllName = dllName; }
public static void GetEntryPoint(string pathOfAssemblyThatContainsEntryPoint, List <Mono.Cecil.AssemblyDefinition> assemblyDefinitions, out Mono.Cecil.MethodDefinition outputMethodDefinition) { // Get the assembly that is supposed to contain the entry point, ie. a class that inherits from "Application": string applicationClassFullName; string assemblyName; string assemblyFullName; ApplicationEntryPointFinder.GetFullNameOfClassThatInheritsFromApplication(pathOfAssemblyThatContainsEntryPoint, out applicationClassFullName, out assemblyName, out assemblyFullName); // Then, find the constructor of that EntryPoint in the AssemblyDefinitions: outputMethodDefinition = null; foreach (Mono.Cecil.AssemblyDefinition assemblyDefinition in assemblyDefinitions) { if (assemblyDefinition.FullName == assemblyFullName) { foreach (Mono.Cecil.ModuleDefinition moduleDefinition in assemblyDefinition.Modules) { foreach (Mono.Cecil.TypeDefinition typeDefinition in moduleDefinition.Types) { if (typeDefinition.FullName == applicationClassFullName) { foreach (Mono.Cecil.MethodDefinition methodDefinition in typeDefinition.Methods) { if (methodDefinition.IsConstructor) { outputMethodDefinition = methodDefinition; break; } } } } } } } }
public Method_Common_CLRSharp(Type_Common_CLRSharp type, Mono.Cecil.MethodDefinition method) { if (method == null) throw new Exception("not allow null method."); this._DeclaringType = type; method_CLRSharp = method; ReturnType = type.env.GetType(method.ReturnType.FullName); ParamList = new MethodParamList(type.env, method); }
public Mono.Cecil.Cil.MethodDebugInformation Read(Mono.Cecil.MethodDefinition method) { throw null; }
private static Accessibility GetAccessibility(this Mono.Cecil.MethodDefinition method) { return(method.IsPublic ? Accessibility.Public : (method.IsAssembly ? Accessibility.Internal : (method.IsFamily ? Accessibility.Protected : Accessibility.Private))); }