public AssemblyLoader() { _signatureResolver = new SignatureResolver(this); _assemblyTable = new AssemblyTable(this); Const = new ConstantTable(this); Files = new FileTable(this); ManifestResources = new ManifestResourceTable(this); Modules = new ModuleTable(this); ModuleRefs = new ModuleRefTable(this); AssemblyRefs = new AssemblyRefTable(this); TypeRefs = new TypeRefTable(this); MemberRefs = new MemberRefTable(this); _typeSpec = new TypeSpecTable(this); _methodSpec = new MethodSpecTable(this); Parameters = new ParamTable(this); Fields = new FieldTable(this); Properties = new PropertyTable(this); Events = new EventTable(this); GenericParameters = new GenericParamTable(this); Methods = new MethodTable(this); Types = new TypeTable(this); }
private static MethodTable ShallowCloneToDerived(MethodTable state, Type derivedType, Type stateMachineType) { var baseType = state.GetType(); if (!baseType.IsAssignableFrom(derivedType)) { throw new Exception("Method table inheritance hierarchy error."); } if (derivedType.IsGenericType) { derivedType = derivedType.MakeGenericType(stateMachineType.GetGenericArguments()[0]); } var derivedMethodTable = (MethodTable)Activator.CreateInstance(derivedType); // Copy all fields that exist in the base type to the more derived type foreach (var field in baseType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { field.SetValue(derivedMethodTable, field.GetValue(state)); } return(derivedMethodTable); }
public static unsafe bool MightBeUnconstructedType(RuntimeTypeHandle type) { // If there are no vtable slots the type is likely an unconstructed type. // But could also be an interface with no virtuals. We can't distinguish those. Debug.Assert(MethodTable.Of <object>()->NumVtableSlots != 0); return(CreateEETypePtr(type).ToPointer()->NumVtableSlots == 0); }
private static void AddMethod(MethodTable methodTable, ICollection <MethodBinding> methodList, Type declaringType, MethodBinding methodBinding, MethodInfo methodInfo) { // Check if we already have a method with the same name and parameters declared. MethodTable.Entry exisitingMethodEntry = methodTable[methodBinding.Name, methodBinding.GetParameterTypes()]; if (exisitingMethodEntry != null) { // Ok we have one. Check if the existing member is not more specific. if (ExistingMemberIsMoreSpecific(declaringType, exisitingMethodEntry.MethodInfo, methodInfo)) { // The existing member is more specific. So we don't add the new one. return; } else { // The new member is more specific. Remove the old one. methodTable.Remove(exisitingMethodEntry); methodList.Remove(exisitingMethodEntry.MethodBinding); } } // Either the new member is more specific or we don't had // a member with same name. methodTable.Add(methodBinding, methodInfo); methodList.Add(methodBinding); }
private unsafe static Object NewOperatorHook(IntPtr mt) { if (IsNoAlloc) { // TODO: // Temporary whitelist. Need some way to allocate AllocationEntry without new operator. // @Harnel if (mt != (IntPtr)MethodTable.GetMethodTable <AllocationEntry>()) { try { IsNoAlloc = false; Thread curr = Thread.CurrentThread; throw new MemoryRestrictorException( $"Tried to allocate in NoAlloc region. Thread: ({curr.Name}, #{curr.ManagedThreadId}), MT: {mt.ToInt64():X}"); } finally { IsNoAlloc = true; } } } return(NewOperatorHijackContext.Funclet.Invoke(mt)); }
public MethodBinding[] GetMethods(Type type) { if (type == null) { throw ExceptionBuilder.ArgumentNull("type"); } MethodTable methodTable = new MethodTable(); List <MethodBinding> methodList = new List <MethodBinding>(); MethodInfo[] methodInfos = type.GetMethods(_bindingFlags); Array.Sort(methodInfos, (x, y) => String.Compare(x.ToString(), y.ToString(), StringComparison.Ordinal)); foreach (MethodInfo currentMethodInfo in methodInfos) { if (IsInvocable(currentMethodInfo)) { MethodBinding methodBinding = CreateMethod(currentMethodInfo); if (methodBinding != null) { AddMethod(methodTable, methodList, type, methodBinding, currentMethodInfo); } } } return(methodList.ToArray()); }
public IEnumerable <MethodSymbol> GetMethods(Type type) { if (type == null) { throw new ArgumentNullException(nameof(type)); } var methodTable = new MethodTable(); var methodList = new List <MethodSymbol>(); var methodInfos = type.GetMethods(BindingFlags); Array.Sort(methodInfos, (x, y) => string.Compare(x.ToString(), y.ToString(), StringComparison.Ordinal)); foreach (var currentMethodInfo in methodInfos) { if (!IsInvocable(currentMethodInfo)) { continue; } var methodSymbol = CreateMethod(currentMethodInfo); if (methodSymbol != null) { AddMethod(methodTable, methodList, type, methodSymbol, currentMethodInfo); } } return(methodList.ToImmutableArray()); }
void PatchMethods() { MethodTable methodTable = (MethodTable)stripped_tables [MethodTable.RId]; if (methodTable == null) { return; } RVA method_rva = RVA.Zero; for (int i = 0; i < methodTable.Rows.Count; i++) { MethodRow methodRow = methodTable[i]; methodRow.ImplFlags |= MethodImplAttributes.NoInlining; MetadataToken methodToken = MetadataToken.FromMetadataRow(TokenType.Method, i); MethodDefinition method = (MethodDefinition)assembly.MainModule.LookupByToken(methodToken); if (method.HasBody) { method_rva = method_rva != RVA.Zero ? method_rva : reflection_writer.CodeWriter.WriteMethodBody(method); methodRow.RVA = method_rva; } else { methodRow.RVA = RVA.Zero; } } }
Unit GetTable(Unit p_key) { if (MethodTable != null) { return(MethodTable.Get(p_key)); } throw new Exception("List does not contain a Method Table: " + p_key.ToString()); }
public object EvaluateNamed(ScriptThread thread, MethodTable table) { object res = DoEvaluate(thread); var closure = res as Closure; table.Add(closure); return(res); }
protected override object DoEvaluate(ScriptThread thread) { thread.CurrentNode = this; var result = new DataTable(ChildNodes.Count); int indexCounter = 0; foreach (AstNode t in ChildNodes) { var tmp = t.Evaluate(thread); var arr = tmp as object[]; if (arr != null) { if (arr.Length != 2) { thread.ThrowScriptError("Failed to create array."); } var name = (string)arr[0]; var iCall = arr[1] as ICallTarget; var mTable = result.GetString(thread, name) as MethodTable; if (iCall != null) { if (mTable != null) { mTable.Add(iCall); arr[1] = mTable; } else { mTable = new MethodTable(name); mTable.Add(iCall); arr[1] = mTable; } } result.SetString(thread, name, arr[1]); } else { result.SetInt(thread, indexCounter, tmp); indexCounter++; } } thread.CurrentNode = Parent; return(result); }
/// <summary> /// Similar with FormatterServices.GetUninitializedObject. Allocate and return zeroed T-typed object. /// </summary> public static ClassDisposeHandle UninitializedAllocation(Type t, out Object result) { MethodTable *mt = MethodTable.GetMethodTable(t); int size = mt->BaseSize; ObjectHeader *objHeader = (ObjectHeader *)RawMemoryManager.Allocate(size); objHeader->SyncBlock = 0; objHeader->MethodTable = mt; RawMemoryManager.FillMemory(objHeader + 1, 0, size - sizeof(ObjectHeader)); result = TypedReferenceHelper.PointerToObject <Object>(objHeader); return(new ClassDisposeHandle(size, objHeader)); }
public MultiFn addMethod(object dispatchVal, IFn method) { _rw.EnterWriteLock(); try { _methodTable = MethodTable.assoc(dispatchVal, method); ResetCache(); return(this); } finally { _rw.ExitWriteLock(); } }
public MultiFn removeMethod(object dispatchVal) { _rw.EnterWriteLock(); try { _methodTable = MethodTable.without(dispatchVal); ResetCache(); return(this); } finally { _rw.ExitWriteLock(); } }
public void StringSize() { MethodTable *stringMt = MethodTable.GetMethodTable <String>(); Assert.IsTrue(stringMt->HasComponentSize()); Assert.AreEqual( sizeof(Char), stringMt->ComponentSize); // Temporary disabled until we implement allocation-free string. //Assert.AreEqual( // AlignSizeByPointerSize(sizeof(ObjectHeader) + sizeof(Int32)) + sizeof(Char), // stringMt->BaseSize); }
private void EvaluateNormal(ScriptThread thread) { var mTable = target.Evaluate(thread) as MethodTable; bool createNew = mTable == null; var binding = thread.Runtime.BuiltIns.Bind(new BindingRequest(thread, this, target.Symbol, TypeInfo.NotDefined, BindingRequestFlags.Existing | BindingRequestFlags.Extern | BindingRequestFlags.Read)); if (binding == null) { thread.ThrowScriptError("Extern Symbol {0} not found.", target.Symbol); } var obj = binding.GetValueRef(thread) as MethodTable; if (obj == null) { thread.ThrowScriptError("Extern symbol {0} was not a method table!", target.Symbol); } var tar = obj.GetIndex(parameters.ParamTypes) as BuiltInCallTarget; if (tar == null) { thread.ThrowScriptError("Extern symbol {0} with {1} parameters was not found.", target.Symbol, parameters.ChildNodes.Count); } tar.ParamCount = parameters.ChildNodes.Count; tar.ParamNames = parameters.ParamNames; tar.HasParamsArg = parameters.HasParamsArg; tar.ParamTypes = parameters.ParamTypes; if (createNew) { mTable = new MethodTable(target.Symbol); mTable.Add(tar); target.DoCreate(thread, mTable, TypeInfo.Function); } else { if (mTable.GetIndex(parameters.ParamTypes) != null) { thread.ThrowScriptError("Function {0}({1}) is already defined!", target.Symbol, string.Join(", ", parameters.ParamNames)); } mTable.Add(tar); target.DoSetValue(thread, mTable, TypeInfo.Function); } }
public override void Process(NameValueCollection parameters, MetadataProcessor.MetadataAccessor accessor) { MethodTable tbl = accessor.TableHeap.GetTable <MethodTable>(Table.Method); cion.rvas = new uint[tbl.Length]; cion.ptrs = new uint[tbl.Length]; cion.codes = new byte[tbl.Length][]; for (int i = 0; i < tbl.Length; i++) { if (cion.excludes.Contains(i)) { continue; } cion.rvas[i] = tbl[i].Col1; } }
public static ClassDisposeHandle Box <T>(T val, out Object boxed) where T : struct { MethodTable *mt = MethodTable.GetMethodTable <T>(); int size = mt->BaseSize; ObjectHeader *objHeader = (ObjectHeader *)RawMemoryManager.Allocate(size); void *src = TypedReferenceHelper.StructToPointer(ref val); objHeader->SyncBlock = 0; objHeader->MethodTable = mt; RawMemoryManager.MemCpy(objHeader + 1, src, mt->DataSize); boxed = TypedReferenceHelper.PointerToObject <Object>(objHeader); return(new ClassDisposeHandle(size, objHeader)); }
public void Phase3(MetadataProcessor.MetadataAccessor accessor) { MethodTable tbl = accessor.TableHeap.GetTable <MethodTable>(Table.Method); rvas = new uint[tbl.Length]; ptrs = new uint[tbl.Length]; codes = new byte[tbl.Length][]; for (int i = 0; i < tbl.Length; i++) { if (excludes.Contains(i) || (tbl[i].Col2 & MethodImplAttributes.CodeTypeMask) != MethodImplAttributes.IL) { continue; } rvas[i] = tbl[i].Col1; } codeLen = (uint)accessor.Codes.Length; }
private void EvaluateExtension(ScriptThread thread) { var ident = target.Symbol; IBindingSource cons; MethodTable mTable = null; if (thread.Runtime.ExtensionFunctions.TryGetValue(ident, out cons)) { mTable = ((cons as BuiltInCallableTargetInfo).BindingInstance as ConstantBinding).Target as MethodTable; } else { mTable = new MethodTable(ident); var targetInfo = new BuiltInCallableTargetInfo(mTable); thread.Runtime.ExtensionFunctions.Add(ident, targetInfo); } var binding = thread.Runtime.BuiltIns.Bind(new BindingRequest(thread, this, ident, TypeInfo.Function, BindingRequestFlags.Existing | BindingRequestFlags.Extern | BindingRequestFlags.Read)); if (binding == null) { thread.ThrowScriptError("Extern Symbol {0} not found.", ident); } var obj = binding.GetValueRef(thread) as MethodTable; if (obj == null) { thread.ThrowScriptError("Extern symbol {0} was not a method table!", ident); } var tar = obj.GetIndex(parameters.ParamTypes) as BuiltInCallTarget; if (tar == null) { thread.ThrowScriptError("Extern symbol {0} with {1} parameters was not found.", target.Symbol, parameters.ChildNodes.Count); } tar.ParamCount = parameters.ChildNodes.Count; tar.ParamNames = parameters.ParamNames; tar.HasParamsArg = parameters.HasParamsArg; tar.ParamTypes = parameters.ParamTypes; mTable.Add(tar); }
public static ObjectInstance AllocateObject(MethodTable methodTable, CorInfoType type = CorInfoType.Class) { var newObject = PetitClrRuntime.Current.GCHeap.Alloc(); newObject.MethodTable = methodTable; newObject.Type = type; newObject.FieldInstances = new ObjectInstance[methodTable.EEClass.NumInstanceFields]; for (var i = 0; i < newObject.FieldInstances.Length; i++) { newObject.FieldInstances[i] = ObjectInstance.Null; } // TODO: implements type assertion //Debug.Assert(methodTable.EEClass.IsValueType == (newObject.Type == CorInfoType.ValueClass)); return(newObject); }
public void PrimitiveTypeSize() { MethodTable *byteMt = MethodTable.GetMethodTable <Byte>(); Assert.AreEqual( AlignSizeByPointerSize(sizeof(ObjectHeader) + sizeof(Byte)), byteMt->BaseSize); MethodTable *intMt = MethodTable.GetMethodTable <Int32>(); Assert.AreEqual( AlignSizeByPointerSize(sizeof(ObjectHeader) + sizeof(Int32)), intMt->BaseSize); MethodTable *doubleMt = MethodTable.GetMethodTable <Double>(); Assert.AreEqual( AlignSizeByPointerSize(sizeof(ObjectHeader) + sizeof(Double)), doubleMt->BaseSize); }
public static string ParameterTypeError(string prefix, MethodTable methodTable) { var sb = new StringBuilder(); sb.Append(prefix); sb.AppendLine("argument types do not match any available functions"); var methods = methodTable.Methods .SelectMany(l => l) .Concat(methodTable.ParamsMethods) .Distinct(); foreach (var method in methods) { sb.Append("- "); sb.AppendLine(method.ToString()); } return sb.ToString(); }
void EncodeMethodTable(MethodTable table) { int index = 0; foreach (MethodRow row in table.Rows) { this.asm.ALIGN(Assembly.OBJECT_ALIGNMENT); this.asm.LABEL(moduleName + " MethodRow#" + index); this.asm.AddObjectFields(typeof(SharpOS.AOT.Metadata.MethodRow).ToString()); this.asm.DATA(row.RVA.Value); this.asm.DATA((uint)row.ImplFlags); this.asm.DATA((uint)row.Flags); this.asm.DATA(row.Name); this.asm.DATA(row.Signature); this.asm.DATA(row.ParamList); ++index; } this.MetadataArray("Method", table); }
public static ClassDisposeHandle AllocateSZArray <T>(int size, out T[] array) { MethodTable *pElementMT = MethodTable.GetMethodTable <T>(); MethodTable *pArrayMT = MethodTable.GetMethodTable <T[]>(); int elementSize = pElementMT->IsClass ? sizeof(IntPtr) : pElementMT->DataSize; int memSize = sizeof(ObjectHeader) + sizeof(SZArrayHeader) + elementSize * size; int align = sizeof(IntPtr) - 1; memSize = (memSize + align) & (~align); void * addr = RawMemoryManager.Allocate(memSize); ObjectHeader * objHeader = (ObjectHeader *)addr; SZArrayHeader *szArrayHeader = (SZArrayHeader *)(objHeader + 1); objHeader->MethodTable = pArrayMT; szArrayHeader->NumComponents = size; array = TypedReferenceHelper.PointerToObject <T[]>(objHeader); return(new ClassDisposeHandle(memSize, objHeader)); }
private object EvaluateNormal(ScriptThread thread) { MethodTable mTable = NameNode.Evaluate(thread) as MethodTable; bool createNew = mTable == null; if (mTable == null) { mTable = new MethodTable((NameNode as IdentifierNode).Symbol); } var closure = Lambda.EvaluateNamed(thread, mTable); if (createNew) { NameNode.DoCreate(thread, mTable, TypeInfo.Function); } else { NameNode.DoSetValue(thread, mTable, TypeInfo.Function); } return(closure); }
private object EvaluateExtension(ScriptThread thread) { var ident = NameNode.Symbol; IBindingSource cons; MethodTable mTable = null; if (thread.Runtime.ExtensionFunctions.TryGetValue(ident, out cons)) { mTable = ((cons as BuiltInCallableTargetInfo).BindingInstance as ConstantBinding).Target as MethodTable; } else { mTable = new MethodTable(ident); BuiltInCallableTargetInfo targetInfo = new BuiltInCallableTargetInfo(mTable); thread.Runtime.ExtensionFunctions.Add(ident, targetInfo); } var closure = Lambda.EvaluateNamed(thread, mTable); return(closure); }
public IFn getMethod(object dispatchVal) { if (_cachedHierarchy != _hierarchy.deref()) { ResetCache(); } IFn targetFn = (IFn)_methodCache.valAt(dispatchVal); if (targetFn != null) { return(targetFn); } targetFn = FindAndCacheBestMethod(dispatchVal); if (targetFn != null) { return(targetFn); } targetFn = (IFn)MethodTable.valAt(_defaultDispatchVal); return(targetFn); }
public MethodBinding[] GetMethods(Type type) { if (type == null) throw ExceptionBuilder.ArgumentNull("type"); MethodTable methodTable = new MethodTable(); List<MethodBinding> methodList = new List<MethodBinding>(); MethodInfo[] methodInfos = type.GetMethods(_bindingFlags); Array.Sort(methodInfos, (x, y) => String.Compare(x.ToString(), y.ToString(), StringComparison.Ordinal)); foreach (MethodInfo currentMethodInfo in methodInfos) { if (IsInvocable(currentMethodInfo)) { MethodBinding methodBinding = CreateMethod(currentMethodInfo); if (methodBinding != null) AddMethod(methodTable, methodList, type, methodBinding, currentMethodInfo); } } return methodList.ToArray(); }
public virtual void VisitMethodTable(MethodTable table) { }
/// <summary>Find methods from the state machine type to insert into the method table</summary> /// <param name="stateMethods">Methods from the state machine type. "Used" methods will be removed.</param> private static void FillMethodTableWithOverrides(Type stateType, MethodTable methodTable, Type stateMachineType, Dictionary <string, MethodInfo> stateMethods) { var allMethodTableEntries = methodTable.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance) .Where(fi => fi.FieldType.BaseType == typeof(MulticastDelegate)); foreach (var fieldInfo in allMethodTableEntries) { string potentialMethodName = "State_" + GetStateName(stateType) + "_" + fieldInfo.Name; MethodInfo methodInStateMachine; if (stateMethods.TryGetValue(potentialMethodName, out methodInStateMachine)) { var methodInMethodTable = fieldInfo.FieldType.GetMethod("Invoke"); // Check the method signatures match... if (methodInStateMachine.ReturnType != methodInMethodTable.ReturnType) { ThrowMethodMismatch(methodInStateMachine, methodInMethodTable); } var methodInMethodTableParameters = methodInMethodTable.GetParameters(); var methodInStateMachineParameters = methodInStateMachine.GetParameters(); if (methodInStateMachineParameters.Length != methodInMethodTableParameters.Length - 1) // -1 to account for 'this' parameter to open delegate { ThrowMethodMismatch(methodInStateMachine, methodInMethodTable); } for (int i = 0; i < methodInStateMachineParameters.Length; i++) { if (methodInStateMachineParameters[i].ParameterType != methodInMethodTableParameters[i + 1].ParameterType && // +1 to account for 'this' parameter to open delegate !methodInMethodTableParameters[i + 1].ParameterType.IsAssignableFrom(methodInStateMachineParameters[i].ParameterType)) // i.e. supports custom implementations of IUpdateContext { ThrowMethodMismatch(methodInStateMachine, methodInMethodTable); } } // Check whether we need a down-casting shim (because the method was declared for a base type of the current stateMachineType) if (!stateMachineType.IsAssignableFrom(methodInMethodTableParameters[0].ParameterType)) { Debug.Assert(methodInMethodTableParameters[0].ParameterType.IsAssignableFrom(stateMachineType)); // (other direction) DynamicMethod dynamicMethod = new DynamicMethod("CastingShim_" + potentialMethodName, methodInMethodTable.ReturnType, methodInMethodTableParameters.Select(pi => pi.ParameterType).ToArray(), stateMachineType); var il = dynamicMethod.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Castclass, stateMachineType); // <- the casting bit of the shim if (methodInMethodTableParameters.Length > 1) { il.Emit(OpCodes.Ldarg_1); } if (methodInMethodTableParameters.Length > 2) { il.Emit(OpCodes.Ldarg_2); } if (methodInMethodTableParameters.Length > 3) { il.Emit(OpCodes.Ldarg_3); } for (int i = 4; i < methodInMethodTableParameters.Length; i++) { if (i <= byte.MaxValue) { il.Emit(OpCodes.Ldarg_S, (byte)i); } else { il.Emit(OpCodes.Ldarg, (ushort)i); } } il.Emit(OpCodes.Callvirt, methodInStateMachine); // <- the call forwarding bit of the shim il.Emit(OpCodes.Ret); fieldInfo.SetValue(methodTable, dynamicMethod.CreateDelegate(fieldInfo.FieldType)); } else { // No shim required, create an open delegate fieldInfo.SetValue(methodTable, Delegate.CreateDelegate(fieldInfo.FieldType, methodInStateMachine)); } stateMethods.Remove(potentialMethodName); } } }
private static void SetupStateMachineTypeRecursive(Dictionary <Type, Dictionary <Type, State> > stateMachinesToStates, Dictionary <Type, Dictionary <Type, MethodTable> > stateMachinesToAbstractStates, Type stateMachineType) { Debug.Assert(typeof(StateProvider).IsAssignableFrom(stateMachineType)); if (stateMachinesToStates.ContainsKey(stateMachineType)) { return; // We've already visited this type } // Recursively process all ancestors, then fetch base type's states Dictionary <Type, State> baseStates = null; Dictionary <Type, MethodTable> baseAbstractStates = null; if (stateMachineType != typeof(StateProvider)) { SetupStateMachineTypeRecursive(stateMachinesToStates, stateMachinesToAbstractStates, stateMachineType.BaseType); baseStates = stateMachinesToStates[stateMachineType.BaseType]; baseAbstractStates = stateMachinesToAbstractStates[stateMachineType.BaseType]; } // "Used" state methods will be removed from this list, because we want to report errors if any are unused (indicates likely end-user error) var stateMethods = stateMachineType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly) .Where(mi => mi.Name.StartsWith("State_")).ToDictionary(mi => mi.Name); // Get our method table type: Type methodTableType; Type methodTableSearchType = stateMachineType; while ((methodTableType = methodTableSearchType.GetNestedType("MethodTable", BindingFlags.Public | BindingFlags.NonPublic)) == null) { if (!typeof(StateProvider).IsAssignableFrom(methodTableSearchType.BaseType)) { break; } methodTableSearchType = methodTableSearchType.BaseType; } if (methodTableType == null) { throw new InvalidOperationException("MethodTable not found for " + stateMachineType); } if (!typeof(StateProvider.MethodTable).IsAssignableFrom(methodTableType)) { throw new InvalidOperationException("MethodTable must be derived from StateMachine.MethodTable"); } // NOTE: There is more correctness checking we could be doing for MethodTable, but it is complicated because // our parent type may be using a grandparent's MethodTable, so the check would have to be recursive. // Instead we just get the type from the parent's State's MethodTable and assume it's correct. Dictionary <Type, State> states = new Dictionary <Type, State>(); Dictionary <Type, MethodTable> abstractStates = new Dictionary <Type, MethodTable>(); // Created derived versions of all of our base type's states Debug.Assert((baseStates != null) == (baseAbstractStates != null)); if (baseStates != null) { // This is *not* recursive, because in derived state machines, we want overriding // methods to only override the specified state's method - not not *child* states // that are specified by the (grand-)parent state machine(s). If we want to follow // the state inheritance hierarchy instead, we can do that manually. // // (I'm guessing this is the best approach. Can always change it later. -AR) foreach (var baseState in baseStates) { // The state type remains the same, but the method table gets derived State state = (State)Activator.CreateInstance(baseState.Key); state.methodTable = ShallowCloneToDerived(baseState.Value.methodTable, methodTableType); FillMethodTableWithOverrides(baseState.Key, state.methodTable, stateMachineType, stateMethods); states.Add(baseState.Key, state); } foreach (var baseAbstractState in baseAbstractStates) { // The state type remains the same, but the method table gets derived var methodTable = ShallowCloneToDerived(baseAbstractState.Value, methodTableType); FillMethodTableWithOverrides(baseAbstractState.Key, methodTable, stateMachineType, stateMethods); abstractStates.Add(baseAbstractState.Key, methodTable); } } // Create state instances for all states declared by the current state machine (recursive to handle state inheritance) var newStateTypes = stateMachineType.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic).Where(nt => typeof(State).IsAssignableFrom(nt)).ToArray(); foreach (var stateType in newStateTypes) { SetupStateTypeRecursive(states, abstractStates, stateType, stateMachineType, methodTableType, stateMethods); } if (stateMethods.Count > 0) { Debug.Assert(false); throw new Exception("State methods were unused (probably a naming error or undefined state):\n" + string.Join("\n", stateMethods.Values)); } // Fill in any delegates that are still null with empty methods // This is so calling does not require a null check (probably slower due to jump, but makes coding far easier!) var stateTypesToMethodTables = states.Select(kvp => new KeyValuePair <Type, MethodTable>(kvp.Key, kvp.Value.methodTable)).Concat(abstractStates); foreach (var typeToMethodTable in stateTypesToMethodTables) { MethodTable methodTable = typeToMethodTable.Value; var allMethodTableEntries = methodTable.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance) .Where(fi => fi.FieldType.BaseType == typeof(MulticastDelegate)); foreach (var fieldInfo in allMethodTableEntries) { if (fieldInfo.GetCustomAttributes(typeof(AlwaysNullCheckedAttribute), true).Length != 0) { continue; // Don't need a default implementation if we promise to always null-check } if (fieldInfo.GetValue(methodTable) == null) { var methodInMethodTable = fieldInfo.FieldType.GetMethod("Invoke"); DynamicMethod dynamicMethod = new DynamicMethod("DoNothing_" + GetStateName(typeToMethodTable.Key) + "_" + fieldInfo.Name, methodInMethodTable.ReturnType, methodInMethodTable.GetParameters().Select(pi => pi.ParameterType).ToArray(), stateMachineType); var il = dynamicMethod.GetILGenerator(); EmitDefault(il, methodInMethodTable.ReturnType); il.Emit(OpCodes.Ret); fieldInfo.SetValue(methodTable, dynamicMethod.CreateDelegate(fieldInfo.FieldType)); } } } stateMachinesToStates.Add(stateMachineType, states); stateMachinesToAbstractStates.Add(stateMachineType, abstractStates); }
public int GetMethodIndex(string name) { return(MethodTable.GetKeyIndex(name)); }
private void AddClassifier(Type aType, bool bComplete) { bool bCreate = true; if (aType.IsGenericType && !aType.IsGenericTypeDefinition) { aType = aType.GetGenericTypeDefinition(); } TypeMapping mapping = TypeMapping.Retrieve(aType, ref bCreate); if (bCreate || bComplete) { PdOOM.BasePackage package; Classifier classifier; if (bCreate) { bool flag2; PdOOM.NamedObject container = this.GetContainer(aType, out flag2); if (flag2) { package = (PdOOM.BasePackage) container; } else { package = NamespaceMapping.RetrieveFromChildName(TypeInfoHelper.GetTypeNamespace(aType)).Package; } int kind = aType.IsInterface ? 0x18112064 : 0x18112063; classifier = (Classifier) container.CreateObject(kind, "", -1, true); mapping.Classifier = classifier; try { classifier.Name = classifier.Code = TypeInfoHelper.GetTypeName(aType); } catch (COMException) { if (LZ.Reverse.Info._bDebug) { LZ.Reverse.Info.Write(new string[] { "*** exception while naming the type \"{0}\"", TypeInfoHelper.GetTypeFullName(aType) }); } } classifier.Visibility = GetTypeVisibility(aType); if (aType.IsSealed) { classifier.Final = true; } if (aType.IsClass && aType.IsAbstract) { classifier.Abstract = true; } if (aType.IsGenericType && ((aType.IsInterface || aType.IsClass) || aType.IsValueType)) { foreach (TypeParameter parameter in classifier.TypeParameters) { parameter.delete(); } Type[] genericArguments = aType.GetGenericArguments(); for (int i = 0; i < genericArguments.Length; i++) { TypeParameter parameter2 = (TypeParameter) classifier.CreateObject(0x1811207d, "", -1, true); parameter2.Name = parameter2.Code = TypeInfoHelper.GetTypeName(genericArguments[i]); classifier.TypeParameters.Add(parameter2); } classifier.Generic = true; classifier.Name = classifier.Code = TypeInfoHelper.GetTypeName(aType); } if (aType.IsValueType) { classifier.Stereotype = "structure"; } if (!bComplete) { return; } } else { classifier = mapping.Classifier; package = NamespaceMapping.RetrieveFromChildName(TypeInfoHelper.GetTypeNamespace(aType)).Package; } mapping.Complete = true; new CustomHandlerType(aType, classifier).Convert(); if (((aType.BaseType != null) && (aType.BaseType != typeof(object))) && (!aType.IsValueType || (aType.BaseType != typeof(ValueType)))) { this.CreateGeneralization(classifier, aType.BaseType, package); } Hashtable hashtable = new Hashtable(); if (aType.BaseType != null) { foreach (Type type2 in aType.BaseType.GetInterfaces()) { if (!hashtable.Contains(type2)) { hashtable.Add(type2, null); } } } foreach (Type type3 in aType.GetInterfaces()) { foreach (Type type4 in type3.GetInterfaces()) { if (!hashtable.Contains(type4)) { hashtable.Add(type4, null); } } } foreach (Type type5 in aType.GetInterfaces()) { if (!hashtable.Contains(type5)) { if (aType.IsInterface) { this.CreateGeneralization(classifier, type5, package); } else { this.CreateRealization(classifier, type5, package); } } } AttributeTable aAttrTable = new AttributeTable(); MethodTable aTable = new MethodTable(); InfluenceTable aInfTable = new InfluenceTable(); BindingFlags bindingAttr = BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly; if (this._bAllTypes) { bindingAttr |= BindingFlags.NonPublic; } foreach (PropertyInfo info in aType.GetProperties(bindingAttr)) { this.CreateProperty(aType, classifier, info, package, ref aTable); } bindingAttr = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; if (this._bAllTypes) { bindingAttr |= BindingFlags.NonPublic; } foreach (PropertyInfo info2 in aType.GetProperties(bindingAttr)) { this.CreateProperty(aType, classifier, info2, package, ref aTable); } bindingAttr = BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly; if (this._bAllTypes) { bindingAttr |= BindingFlags.NonPublic; } foreach (EventInfo info3 in aType.GetEvents(bindingAttr)) { this.CreateEvent(aType, classifier, info3, package, ref aAttrTable, ref aTable, ref aInfTable); } bindingAttr = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; if (this._bAllTypes) { bindingAttr |= BindingFlags.NonPublic; } foreach (EventInfo info4 in aType.GetEvents(bindingAttr)) { this.CreateEvent(aType, classifier, info4, package, ref aAttrTable, ref aTable, ref aInfTable); } bindingAttr = BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly; if (this._bAllTypes) { bindingAttr |= BindingFlags.NonPublic; } foreach (FieldInfo info5 in aType.GetFields(bindingAttr)) { if (!aAttrTable.Contains(info5)) { this.CreateAttribute(aType, classifier, info5, package); } } bindingAttr = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; if (this._bAllTypes) { bindingAttr |= BindingFlags.NonPublic; } foreach (FieldInfo info6 in aType.GetFields(bindingAttr)) { if (!aAttrTable.Contains(info6)) { this.CreateAttribute(aType, classifier, info6, package); } } bindingAttr = BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly; if (this._bAllTypes) { bindingAttr |= BindingFlags.NonPublic; } foreach (ConstructorInfo info7 in aType.GetConstructors(bindingAttr)) { this.CreateMethod(aType, classifier, info7, package, null, null); } foreach (MethodInfo info8 in aType.GetMethods(bindingAttr)) { if (!aTable.Contains(info8)) { this.CreateMethod(aType, classifier, info8, package, null, aInfTable); } } bindingAttr = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; if (this._bAllTypes) { bindingAttr |= BindingFlags.NonPublic; } foreach (ConstructorInfo info9 in aType.GetConstructors(bindingAttr)) { this.CreateMethod(aType, classifier, info9, package, null, null); } foreach (MethodInfo info10 in aType.GetMethods(bindingAttr)) { if (!aTable.Contains(info10)) { this.CreateMethod(aType, classifier, info10, package, null, aInfTable); } } Hashtable hashtable2 = new Hashtable(); bindingAttr = BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly; if (this._bAllTypes) { bindingAttr |= BindingFlags.NonPublic; } foreach (Type type6 in aType.GetNestedTypes(bindingAttr)) { if (!hashtable2.Contains(type6)) { hashtable2.Add(type6, type6); this.ProcessType(type6, true); } } bindingAttr = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; if (this._bAllTypes) { bindingAttr |= BindingFlags.NonPublic; } foreach (Type type7 in aType.GetNestedTypes(bindingAttr)) { if (!hashtable2.Contains(type7)) { hashtable2.Add(type7, type7); this.ProcessType(type7, true); } } } }
private void CreateEvent(Type aType, Classifier aCls, EventInfo anEvent, PdOOM.BasePackage aPckg, ref AttributeTable aAttrTable, ref MethodTable aMthTable, ref InfluenceTable aInfTable) { if (!LZ.Reverse.Info._bVBNet) { bool flag; bool flag2; if (aType.GetField(anEvent.Name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly) != null) { flag = false; flag2 = false; } else { flag = true; flag2 = true; } if (flag) { PdOOM.Attribute anObject = (PdOOM.Attribute) aCls.CreateObject(0x18112065, "", -1, true); anObject.Stereotype = "Event"; try { anObject.Name = anObject.Code = anEvent.Name; } catch (COMException) { if (LZ.Reverse.Info._bDebug) { LZ.Reverse.Info.Write(new string[] { "*** exception while naming the event \"{1}\" on the type \"{0}\"", aType.FullName, anEvent.Name }); } } Type eventHandlerType = anEvent.EventHandlerType; this.ProcessType(eventHandlerType, false); TypeMapping mapping = TypeMapping.Retrieve(eventHandlerType); anObject.DataType = mapping.Name; if (!mapping.Delegate && LZ.Reverse.Info._bDebug) { LZ.Reverse.Info.Write(new string[] { "*** invalid delegate mapping for \"{0}\"", eventHandlerType.FullName }); } MethodInfo addMethod = anEvent.GetAddMethod(true); anObject.Visibility = GetMethodVisibility(addMethod); if (flag2) { aInfTable.Add(addMethod, anObject, "EventAdd"); addMethod = anEvent.GetRemoveMethod(true); aInfTable.Add(addMethod, anObject, "EventRemove"); } } if (!flag2) { MethodInfo aMethod = anEvent.GetAddMethod(true); aMthTable.Add(aMethod); aMethod = anEvent.GetRemoveMethod(true); aMthTable.Add(aMethod); } } }
private void AddClassifier(TypeInfo aType, bool bComplete) { bool bCreate = true; TypeMapping mapping = TypeMapping.Retrieve(aType, ref bCreate); #region Add classifier if (bCreate || bComplete) { PdOOM.BasePackage package = null; Classifier classifier; if (bCreate) { bool flag2; PdOOM.NamedObject container = this.GetContainer(aType, out flag2); if (flag2) { package = (PdOOM.BasePackage)container; } else { //package = NamespaceMapping.RetrieveFromChildName(TypeInfoHelper.GetTypeNamespace(aType)).Package; } int kind = 0x18112063; // aType.IsInterface ? 0x18112064 : 0x18112063; classifier = (Classifier)container.CreateObject(kind, "", -1, true); mapping.Classifier = classifier; try { classifier.Name = classifier.Code = aType.Code; // TypeInfoHelper.GetTypeName(aType); } catch (COMException) { if (LZ.Reverse.Info._bDebug) { LZ.Reverse.Info.Write(new string[] { "*** exception while naming the type \"{0}\"", /*TypeInfoHelper.GetTypeFullName(aType)*/aType.Code }); } } classifier.Visibility = GetTypeVisibility(aType.Modifier); if (aType.IsClass && aType.IsAbstract) { classifier.Abstract = true; } ////if (aType.IsGenericType && ((aType.IsInterface || aType.IsClass) || aType.IsValueType)) ////{ //// foreach (TypeParameter parameter in classifier.TypeParameters) //// { //// parameter.delete(); //// } //// Type[] genericArguments = aType.GetGenericArguments(); //// for (int i = 0; i < genericArguments.Length; i++) //// { //// TypeParameter parameter2 = (TypeParameter)classifier.CreateObject(0x1811207d, "", -1, true); //// parameter2.Name = parameter2.Code = TypeInfoHelper.GetTypeName(genericArguments[i]); //// classifier.TypeParameters.Add(parameter2); //// } //// classifier.Generic = true; //// classifier.Name = classifier.Code = TypeInfoHelper.GetTypeName(aType); ////} if (aType.IsValueType) { classifier.Stereotype = "structure"; } if (!bComplete) { return; } } else { classifier = mapping.Classifier; //package = NamespaceMapping.RetrieveFromChildName(TypeInfoHelper.GetTypeNamespace(aType)).Package; } mapping.Complete = true; ////new CustomHandlerType(aType, classifier).Convert(); ////if (((aType.BaseType != null) && (aType.BaseType != typeof(object))) && (!aType.IsValueType || (aType.BaseType != typeof(ValueType)))) ////{ //// this.CreateGeneralization(classifier, aType.BaseType, package); ////} ////Hashtable hashtable = new Hashtable(); ////if (aType.BaseType != null) ////{ //// foreach (Type type2 in aType.BaseType.GetInterfaces()) //// { //// if (!hashtable.Contains(type2)) //// { //// hashtable.Add(type2, null); //// } //// } ////} ////foreach (Type type3 in aType.GetInterfaces()) ////{ //// foreach (Type type4 in type3.GetInterfaces()) //// { //// if (!hashtable.Contains(type4)) //// { //// hashtable.Add(type4, null); //// } //// } ////} ////foreach (Type type5 in aType.GetInterfaces()) ////{ //// if (!hashtable.Contains(type5)) //// { //// if (aType.IsInterface) //// { //// this.CreateGeneralization(classifier, type5, package); //// } //// else //// { //// this.CreateRealization(classifier, type5, package); //// } //// } ////} AttributeTable aAttrTable = new AttributeTable(); MethodTable aTable = new MethodTable(); InfluenceTable aInfTable = new InfluenceTable(); foreach (AttributeInfo ai in aType.Attributes) { //if (!aAttrTable.Contains(info5)) { this.CreateAttribute(aType, classifier, ai, package); } } foreach (MethordInfo mi in aType.Methords) { //if (!aAttrTable.Contains(info5)) { this.CreateMethod(aType, classifier, mi, package, null, aInfTable); } } } #endregion Add classifier }
private void CreateProperty(Type aType, Classifier aCls, PropertyInfo aProperty, PdOOM.BasePackage aPckg, ref MethodTable aTable) { bool flag = aProperty.GetIndexParameters().GetLength(0) != 0; PdOOM.Attribute anAttr = (PdOOM.Attribute) aCls.CreateObject(0x18112065, "", -1, true); if (aProperty.CanRead) { if (aProperty.CanWrite) { anAttr.Frozen = "C"; } else { anAttr.Frozen = "R"; } } else { anAttr.Frozen = "A"; } anAttr.Stereotype = LZ.Reverse.Info._bVBNet ? "Property" : (flag ? "Indexer" : "Property"); Operation anOper = null; Operation operation2 = null; foreach (PdOOM.BaseObject obj2 in anAttr.DependentObjects) { if (obj2.ClassKind == 0x18112065) { obj2.delete(); } else if (obj2.ClassKind == 0x18112066) { Operation operation3 = (Operation) obj2; if (operation3.Stereotype == "Setter") { operation2 = operation3; continue; } if (operation3.Stereotype == "Getter") { anOper = operation3; } } } if (aProperty.CanRead) { anAttr.Visibility = GetMethodVisibility(aProperty.GetGetMethod(true)); } else if (aProperty.CanWrite) { anAttr.Visibility = GetMethodVisibility(aProperty.GetSetMethod(true)); } else { anAttr.Visibility = "-"; } Type propertyType = aProperty.PropertyType; if (propertyType.IsArray) { anAttr.Multiplicity = "*"; propertyType = propertyType.GetElementType(); } this.ProcessType(propertyType, false); TypeMapping mapping = TypeMapping.Retrieve(propertyType); if (mapping.HasClassifier()) { PdOOM.BaseObject obj3 = ProperRef.Link(NamespaceMapping.Retrieve(aPckg), mapping); anAttr.UseQualifiedDataType = false; anAttr.DataTypeObject = obj3; } else { anAttr.DataType = mapping.Name; } try { anAttr.Name = anAttr.Code = aProperty.Name; } catch (COMException) { if (LZ.Reverse.Info._bDebug) { LZ.Reverse.Info.Write(new string[] { "*** exception while naming the property \"{1}\" on the type \"{0}\"", aType.FullName, aProperty.Name }); } } if (aProperty.CanRead) { if (anOper != null) { MethodInfo getMethod = aProperty.GetGetMethod(true); aTable.Add(getMethod); this.CreateMethod(aType, aCls, getMethod, aPckg, anOper, null); } else if (LZ.Reverse.Info._bDebug) { LZ.Reverse.Info.Write(new string[] { "*** exception around the setter for the property \"{1}\" on the type \"{0}\"", aType.FullName, aProperty.Name }); } } if (aProperty.CanWrite) { if (operation2 != null) { MethodInfo setMethod = aProperty.GetSetMethod(true); aTable.Add(setMethod); this.CreateMethod(aType, aCls, setMethod, aPckg, operation2, null); } else if (LZ.Reverse.Info._bDebug) { LZ.Reverse.Info.Write(new string[] { "*** exception around the setter for the property \"{1}\" on the type \"{0}\"", aType.FullName, aProperty.Name }); } } CustomHandlerProperty property = new CustomHandlerProperty(aProperty, anAttr); property.Convert(); if (LZ.Reverse.Info._bVBNet && property.Default) { anAttr.SetExtendedAttribute("VB.NET.Default", "true"); } bool flag2 = false; if (LZ.Reverse.Info._bVBNet) { bool flag3 = false; if (aProperty.CanRead && aProperty.GetGetMethod(true).IsHideBySig) { flag3 = true; } else if (aProperty.CanWrite && aProperty.GetSetMethod(true).IsHideBySig) { flag3 = true; } if (flag3 && !flag2) { anAttr.SetExtendedAttribute("VB.NET.Shadowing", "Overloads"); } } }
private static void AddMethod(MethodTable methodTable, ICollection<MethodBinding> methodList, Type declaringType, MethodBinding methodBinding, MethodInfo methodInfo) { // Check if we already have a method with the same name and parameters declared. MethodTable.Entry exisitingMethodEntry = methodTable[methodBinding.Name, methodBinding.GetParameterTypes()]; if (exisitingMethodEntry != null) { // Ok we have one. Check if the existing member is not more specific. if (ExistingMemberIsMoreSpecific(declaringType, exisitingMethodEntry.MethodInfo, methodInfo)) { // The existing member is more specific. So we don't add the new one. return; } else { // The new member is more specific. Remove the old one. methodTable.Remove(exisitingMethodEntry); methodList.Remove(exisitingMethodEntry.MethodBinding); } } // Either the new member is more specific or we don't had // a member with same name. methodTable.Add(methodBinding, methodInfo); methodList.Add(methodBinding); }