RuntimeMethod ITypeSystem.GetImplementationForInternalCall(RuntimeMethod internalCall) { Debug.Assert(internalCall != null, @"internalCall is null."); if (null == internalCall) { throw new ArgumentNullException(@"internalCall"); } // Return value RuntimeMethod result = null; // Shortcut: If the call was resolved previously, scan it there if (this.internalCallTargets.TryGetValue(internalCall, out result)) { return(result); } /* * FIXME: * - The following sequence requires that mscorlib is available in the test runtime. * - Maybe we should be smarter about its use though. * - Commented out right now, as we don't load assembly dependencies yet. */ ITypeSystem ts = (ITypeSystem)this; // FIXME: Include this when we're loading mscorlib //RuntimeType rtMia = ts.GetType(@"System.Runtime.CompilerServices.MethodImplAttribute"); //MethodImplAttribute mia = (MethodImplAttribute)internalCall.GetAttributes(rtMia, true); //Debug.Assert(MethodImplOptions.InternalCall == (mia.Value & MethodImplOptions.InternalCall), @"Method is not InternalCall."); //if (MethodImplOptions.InternalCall != (mia.Value & MethodImplOptions.InternalCall)) // throw new ArgumentException(@"Method not marked as an InternalCall.", @"internalCall"); RuntimeType callImplType = ts.GetType("Mosa.Runtime.Vm.InternalCallImplAttribute"); object[] callDefAttrs = internalCall.GetCustomAttributes(callImplType); Debug.Assert(0 != callDefAttrs.Length, @"No runtime call definition for icall!"); Debug.Assert(1 == callDefAttrs.Length, @"Only one call definition for icall supported! Additional ones ignored!"); InternalCallImplAttribute callDef = (InternalCallImplAttribute)callDefAttrs[0]; // Scan all known types for icalls foreach (RuntimeType rType in internalTypes) { foreach (RuntimeMethod rMethod in rType.Methods) { object[] callImpls = rMethod.GetCustomAttributes(callImplType); foreach (InternalCallImplAttribute callImpl in callImpls) { if (callDef.Match(callImpl) == true) { // We found the sought icall, save it and return it this.internalCallTargets[internalCall] = rMethod; return(rMethod); } } } } throw new NotImplementedException(@"Requested InternalCall not loaded or not implemented."); }
/// <summary> /// When overridden in a derived class, returns a value that indicates whether this instance equals a specified object. /// </summary> /// <param name="obj">An <see cref="T:System.Object"/> to compare with this instance of <see cref="T:System.Attribute"/>.</param> /// <returns> /// true if this instance equals <paramref name="obj"/>; otherwise, false. /// </returns> public override bool Match(object obj) { InternalCallImplAttribute icia = obj as InternalCallImplAttribute; if (icia != null) { return(Match(icia)); } return(false); }
/// <summary> /// Checks if this attribute matches the specified attribute. /// </summary> /// <param name="call">The call attribute.</param> /// <returns><c>true</c> if they match; otherwise <c>false</c>.</returns> public abstract bool Match(InternalCallImplAttribute call);
/// <summary> /// Checks if this attribute matches the specified attribute. /// </summary> /// <param name="call">The call attribute.</param> /// <returns> /// <c>true</c> if they match; otherwise <c>false</c>. /// </returns> public sealed override bool Match(InternalCallImplAttribute call) { VmCallAttribute vmCall = call as VmCallAttribute; return(vmCall != null && vmCall.RuntimeCall == this.RuntimeCall); }
/// <summary> /// Checks if this attribute matches the specified attribute. /// </summary> /// <param name="call">The call attribute.</param> /// <returns> /// <c>true</c> if they match; otherwise <c>false</c>. /// </returns> public override sealed bool Match(InternalCallImplAttribute call) { VmCallAttribute vmCall = call as VmCallAttribute; return (vmCall != null && vmCall.RuntimeCall == this.RuntimeCall); }