private int GetDepth(ClrType curr) { int depth = 0; while (curr != null) { curr = curr.BaseType; depth++; } return depth; }
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; }
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(); } }