Beispiel #1
0
        private int GetDepth(ClrType curr)
        {
            int depth = 0;
            while (curr != null)
            {
                curr = curr.BaseType;
                depth++;
            }

            return depth;
        }
Beispiel #2
0
        private ClrType TryBuildType(ClrHeap heap)
        {
            var runtime = heap.GetRuntime();
            var domains = runtime.AppDomains;
            ClrType[] types = new ClrType[domains.Count];

            ClrElementType elType = ElementType;
            if (ClrRuntime.IsPrimitive(elType) || elType == ClrElementType.String)
                return ((DesktopGCHeap)heap).GetBasicType(elType);

            int count = 0;
            foreach (var domain in domains)
            {
                object value = GetValue(domain);
                if (value != null && value is ulong && ((ulong)value != 0))
                {
                    types[count++] = heap.GetObjectType((ulong)value);
                }
            }

            int depth = int.MaxValue;
            ClrType result = null;
            for (int i = 0; i < count; ++i)
            {
                ClrType curr = types[i];
                if (curr == result || curr == null)
                    continue;

                int nextDepth = GetDepth(curr);
                if (nextDepth < depth)
                {
                    result = curr;
                    depth = nextDepth;
                }
            }

            return result;
        }
Beispiel #3
0
		private void AnalyzeBaseCtorCallParams(Analyzer/*!*/ analyzer, ClrType/*!*/ clrBase)
		{
			// we needn't to resolve the ctor here since the base class has to be known CLR type,
			// which has always a known ctor (may be a stub):
			ClrMethod base_ctor = clrBase.ClrConstructor;

			// create non-generic call signature:
			CallSignature call_sig = new CallSignature(baseCtorParams, TypeRef.EmptyList);

			RoutineSignature signature;
			int overload_index = base_ctor.ResolveOverload(analyzer, call_sig, position, out signature);

			if (overload_index == DRoutine.InvalidOverloadIndex)
			{
				analyzer.ErrorSink.Add(Errors.ClassHasNoVisibleCtor, analyzer.SourceUnit, position, clrBase.FullName);
			}
			else if (base_ctor.Overloads[overload_index].MandatoryParamCount != call_sig.Parameters.Count)
			{
				// invalid argument count passed to the base ctor:
				analyzer.ErrorSink.Add(Errors.InvalidArgumentCount, analyzer.SourceUnit, position);
			}

			call_sig.Analyze(analyzer, signature, AST.ExInfoFromParent.DefaultExInfo, true);

			// stores the signature on the type builder:
			method.DeclaringPhpType.Builder.BaseCtorCallSignature = call_sig;
			method.DeclaringPhpType.Builder.BaseCtorCallOverloadIndex = overload_index;

			// we don't need it any more:
			baseCtorParams = null;
		}
	// Define a data field within this class.
	private FieldBuilder DefineData(String name, byte[] data,
								    int size, FieldAttributes attributes)
			{
				// Validate the parameters.
				if(name == null)
				{
					throw new ArgumentNullException("name");
				}
				else if(name == String.Empty)
				{
					throw new ArgumentException(_("Emit_NameEmpty"));
				}
				else if(size <= 0 || size > 0x003EFFFF)
				{
					throw new ArgumentException(_("Emit_DataSize"));
				}

				// We must not have created the type yet.
				CheckNotCreated();

				// Look for or create a value type for the field.
				String typeName = "$ArrayType$" + size.ToString();
				Type type = module.GetType(typeName);
				if(type == null)
				{
					TypeBuilder builder;
					builder = module.DefineType
							(typeName,
							 TypeAttributes.Public |
							 TypeAttributes.Sealed |
							 TypeAttributes.ExplicitLayout,
							 typeof(System.ValueType),
							 PackingSize.Size1, size);
					type = builder.CreateType();
				}

				// Define the field and set the data on it.
				FieldBuilder field = DefineField
					(name, type, attributes | FieldAttributes.Static);
				field.SetData(data, size);
				return field;
			}
	// Constructor.
	internal TypeBuilder(ModuleBuilder module, String name, String nspace,
						 TypeAttributes attr, Type parent, Type[] interfaces,
						 PackingSize packingSize, int typeSize,
						 TypeBuilder declaringType)
			{
				// Validate the parameters.
				if(name == null)
				{
					throw new ArgumentNullException("name");
				}
				else if(name == String.Empty)
				{
					throw new ArgumentException(_("Emit_NameEmpty"));
				}
				if(nspace == null)
				{
					nspace = String.Empty;
				}

				// Initialize the internal state.
				this.module = module;
				this.name = name;
				this.nspace = nspace;
				this.attr = attr;
				this.parent = parent;
				this.interfaces = null;
				this.declaringType = declaringType;
				this.type = null;
				this.underlyingSystemType = null;
				this.methods = new ArrayList();
				this.needsDefaultConstructor = true;

				// We need the AssemblyBuilder lock for the next part.
				lock(typeof(AssemblyBuilder))
				{
					// Determine the scope to use to declare the type.
					IntPtr scope;
					if(declaringType == null)
					{
						scope = IntPtr.Zero;
					}
					else
					{
						scope = ((IClrProgramItem)declaringType).ClrHandle;
					}

					// Create the type.
					privateData = ClrTypeCreate
						(((IClrProgramItem)module).ClrHandle, scope, name,
					 	(nspace == String.Empty ? null : nspace), attr,
					 	(parent == null
							? new System.Reflection.Emit.TypeToken(0)
					 		: module.GetTypeToken(parent)));
					if(privateData == IntPtr.Zero)
					{
						throw new ArgumentException
							(_("Emit_TypeAlreadyExists"));
					}
					module.assembly.AddDetach(this);
					if(packingSize != PackingSize.Unspecified)
					{
						ClrTypeSetPackingSize(privateData, (int)packingSize);
					}
					if(typeSize != UnspecifiedTypeSize)
					{
						ClrTypeSetClassSize(privateData, typeSize);
					}
				}

				// Add the interfaces to the type.
				if(interfaces != null)
				{
					foreach(Type iface in interfaces)
					{
						AddInterfaceImplementation(iface);
					}
				}
			}
	// Create this type.
	public Type CreateType()
			{
				try
				{
					// Synchronize access and make sure we aren't created.
					StartSync();

					// If nested, the nesting parent must be created first.
					if(declaringType != null)
					{
						if(declaringType.type == null)
						{
							throw new InvalidOperationException
								(_("Emit_NestingParentNotCreated"));
						}
					}

					// Define a default constructor if necessary.
					if(needsDefaultConstructor && !IsInterface && !IsValueType)
					{
						if(IsAbstract)
						{
							DefineDefaultConstructor(MethodAttributes.Family);
						}
						else
						{
							DefineDefaultConstructor(MethodAttributes.Public);
						}
					}

					// Finalize the methods and constructors.
					MethodBuilder mb;
					foreach(MethodBase method in methods)
					{
						mb = (method as MethodBuilder);
						if(mb != null)
						{
							mb.FinalizeMethod();
						}
						else
						{
							((ConstructorBuilder)method).FinalizeConstructor();
						}
					}

					// Wrap "privateData" in a "ClrType" object and return it.
					lock(typeof(AssemblyBuilder))
					{
						if(privateData == IntPtr.Zero)
						{
							throw new InvalidOperationException
								(_("Emit_TypeInvalid"));
						}
						ClrType clrType = new ClrType();
						clrType.privateData = privateData;
						type = clrType;
						return type;
					}
				}
				finally
				{
					EndSync();
				}
			}