예제 #1
0
        /// <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);
            }
        }
예제 #2
0
 /// <summary>
 /// IL ctor
 /// </summary>
 public MethodSource(XMethodDefinition method, ILMethodDefinition ilMethod)
 {
     if (ilMethod == null)
         throw new ArgumentNullException();
     this.method = method;
     this.ilMethod = ilMethod;
 }
예제 #3
0
        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();
        }
예제 #4
0
		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 ());
		}
예제 #5
0
        void RemoveInstruction(MethodDefinition method, Func <Instruction, bool> where)
        {
            var il = method.Body.GetILProcessor();

            il.Remove(method.Body.Instructions.First(where));
        }
예제 #6
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public DexImportMethodBuilder(AssemblyCompiler compiler, MethodDefinition method)
     : base(compiler, method)
 {
 }
예제 #7
0
        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);
        }
예제 #8
0
파일: Context.cs 프로젝트: zhangf911/LSharp
        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);
        }
예제 #9
0
        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();
        }
예제 #10
0
		protected abstract TType[] GetParameters (TMethod method);
예제 #11
0
		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);
예제 #12
0
			public ObjCMethod (Registrar registrar, ObjCType declaringType, TMethod method)
				: base (registrar, declaringType)
			{
				Method = method;
			}
예제 #13
0
		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 ();
		}
예제 #14
0
		// 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;
		}
예제 #15
0
        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);
        }
예제 #16
0
        //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);
        }
예제 #17
0
		protected abstract string GetParameterName (TMethod method, int parameter_index);
예제 #18
0
 public MethodEntry(Mono.Cecil.MethodDefinition mdef)
 {
     m_mdef = mdef;
 }
예제 #19
0
		protected abstract bool IsVirtual (TMethod method);
예제 #20
0
        /// <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);
        }
예제 #21
0
		protected abstract bool IsStatic (TMethod method);
예제 #22
0
 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));
 }
예제 #23
0
		protected abstract bool HasThisAttribute (TMethod method);
예제 #24
0
 /// <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;
 }
예제 #25
0
		protected abstract bool IsConstructor (TMethod method);
예제 #26
0
		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;
		}
예제 #27
0
		protected abstract TType GetReturnType (TMethod method);
예제 #28
0
        /// <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);
        }
예제 #29
0
		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).
예제 #30
0
        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);
                    }
                }
            }
        }
예제 #31
0
		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.
예제 #32
0
        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);
                            }
                        }
                    }
                }
            }
        }
예제 #33
0
		protected abstract bool IsGenericMethod (TMethod method);
예제 #34
0
		protected abstract Exception CreateException (int code, Exception innerException, TMethod method, string message, params object[] args);
예제 #35
0
		protected abstract string GetMethodName (TMethod method);
예제 #36
0
        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];
                }
            }
        }
예제 #37
0
		protected Exception CreateException (int code, TMethod method, string message, params object[] args)
		{
			return CreateException (code, null, method, message, args);
		}
예제 #38
0
 //以后准备用自定义Body采集一遍,可以先过滤处理掉Mono.Cecil的代码中的指向,执行会更快
 public CodeBody(CLRSharp.ICLRSharp_Environment env, Mono.Cecil.MethodDefinition _def)
 {
     this.method = _def;
     Init(env);
 }
예제 #39
0
		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 ();
		}
예제 #40
0
        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);
        }
예제 #41
0
		string GetDescriptiveMethodName (TType type, TMethod method)
		{
			return GetTypeFullName (type) + "." + GetDescriptiveMethodName (method);
		}
예제 #42
0
 /// <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)
 {
 }
예제 #43
0
 /// <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;
 }
예제 #44
0
        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);
        }
예제 #45
0
파일: CodeBody.cs 프로젝트: xqy/game
 //以后准备用自定义Body采集一遍,可以先过滤处理掉Mono.Cecil的代码中的指向,执行会更快
 public CodeBody(CLRSharp.ICLRSharp_Environment env, Mono.Cecil.MethodDefinition _def)
 {
     this.method = _def;
     Init(env);
 }
예제 #46
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));
 }
예제 #47
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public DexImportMethodBuilder(AssemblyCompiler compiler, MethodDefinition method)
     : base(compiler, method)
 {
 }
예제 #48
0
 /// <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;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #50
0
        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);
        }
예제 #51
0
 public Mono.Cecil.Cil.MethodDebugInformation Read(Mono.Cecil.MethodDefinition method)
 {
     throw null;
 }
예제 #52
0
 /// <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;
 }
예제 #53
0
 private static Accessibility GetAccessibility(this Mono.Cecil.MethodDefinition method)
 {
     return(method.IsPublic ? Accessibility.Public :
            (method.IsAssembly ? Accessibility.Internal : (method.IsFamily ? Accessibility.Protected : Accessibility.Private)));
 }