public abstract IntPtr OnEntryPoint(MethodEntrypointPtr entrypointInfo, IntPtr callerArgumentsInfo);
        public static bool TryGetMethodEntrypoint(MethodDesc methodOnType, out IntPtr entryPoint, out IntPtr unboxingStubAddress, out TypeLoaderEnvironment.MethodAddressType foundAddressType)
        {
            MethodDesc typicalMethod = methodOnType.GetTypicalMethodDefinition();

            if (!(typicalMethod is EcmaMethod))
            {
                foundAddressType    = TypeLoaderEnvironment.MethodAddressType.None;
                entryPoint          = IntPtr.Zero;
                unboxingStubAddress = IntPtr.Zero;
                return(false);
            }

            // OK, this is a method entrypoint for an ecma method
            EcmaMethod ecmaTypicalMethod = (EcmaMethod)typicalMethod;

            // Canonicalize
            MethodDesc canonMethod = methodOnType.GetCanonMethodTarget(CanonicalFormKind.Specific);

            if (canonMethod != methodOnType)
            {
                foundAddressType = TypeLoaderEnvironment.MethodAddressType.Canonical;
            }
            else
            {
                foundAddressType = TypeLoaderEnvironment.MethodAddressType.Exact;
            }


            // Check to see if we should produce an unboxing stub entrypoint

            unboxingStubAddress = IntPtr.Zero; // Optimistically choose not to
            if (ecmaTypicalMethod.OwningType.IsValueType)
            {
                MethodSignature methodSig = ecmaTypicalMethod.Signature;
                if (!methodSig.IsStatic)
                {
                    unboxingStubAddress = new IntPtr(5); // TODO Actually implement the unboxing stub logic
                }
            }

            // Ensure RuntimeTypeHandles for owningType, and for instantiation types
            // They should be there, as the paths to this function should ensure it, but its a bit sketchy
            // as we don't have an opportunity to easily compute them now
            if (!canonMethod.OwningType.RetrieveRuntimeTypeHandleIfPossible())
            {
                Environment.FailFast("Did not pre-allocate owning type typehandle");
            }

            foreach (TypeDesc type in canonMethod.Instantiation)
            {
                if (!type.RetrieveRuntimeTypeHandleIfPossible())
                {
                    Environment.FailFast("Did not pre-allocate instantiation type typehandle");
                }
            }

            // We need to create a RuntimeMethodHandle for this method
            MethodEntrypointPtr entrypoint = s_methodEntrypointHash.GetOrCreateValue(new MethodEntrypointLookup(canonMethod));

            if (entrypoint.MethodCode != IntPtr.Zero)
            {
                entryPoint = entrypoint.MethodCode;
            }
            else
            {
                entryPoint = entrypoint.MethodEntrypointThunk;
            }

            return(true);
        }