public static unsafe void ActivatorCreateInstanceAny(ref object ptrToData, IntPtr pEETypePtr) { EETypePtr pEEType = new EETypePtr(pEETypePtr); if (pEEType.IsValueType) { // Nothing else to do for value types. return; } // For reference types, we need to: // 1- Allocate the new object // 2- Call its default ctor // 3- Update ptrToData to point to that newly allocated object ptrToData = RuntimeImports.RhNewObject(pEEType); Entry entry = LookupInCache(s_cache, pEETypePtr, pEETypePtr); if (entry == null) { entry = CacheMiss(pEETypePtr, pEETypePtr, (IntPtr context, IntPtr signature, object contextObject, ref IntPtr auxResult) => { IntPtr result = RuntimeAugments.TypeLoaderCallbacks.TryGetDefaultConstructorForType(new RuntimeTypeHandle(new EETypePtr(context))); if (result == IntPtr.Zero) { result = RuntimeAugments.GetFallbackDefaultConstructor(); } return(result); }); } RawCalliHelper.Call(entry.Result, ptrToData); }
public static object GenericLookupAndAllocArray(IntPtr context, IntPtr arg, IntPtr signature) { Entry entry = LookupInCache(s_cache, context, signature); entry ??= CacheMiss(context, signature); return(RawCalliHelper.Call <object>(entry.Result, entry.AuxResult, arg)); }
public static void GenericLookupAndCallCtor(object arg, IntPtr context, IntPtr signature) { Entry entry = LookupInCache(s_cache, context, signature); entry ??= CacheMiss(context, signature); RawCalliHelper.Call(entry.Result, arg); }
public static void GenericLookupAndCheckArrayElemType(IntPtr context, object arg, IntPtr signature) { Entry entry = LookupInCache(s_cache, context, signature); entry ??= CacheMiss(context, signature); RawCalliHelper.Call(entry.Result, entry.AuxResult, arg); }
public static Object GenericLookupAndCast(Object arg, IntPtr context, IntPtr signature) { Entry entry = LookupInCache(s_cache, context, signature); if (entry == null) { entry = CacheMiss(context, signature); } return(RawCalliHelper.Call <Object>(entry.Result, arg, entry.AuxResult)); }
public static unsafe void ActivatorCreateInstanceAny(ref object ptrToData, IntPtr pEETypePtr) { EETypePtr pEEType = new EETypePtr(pEETypePtr); if (pEEType.IsValueType) { // Nothing else to do for value types. return; } // For reference types, we need to: // 1- Allocate the new object // 2- Call its default ctor // 3- Update ptrToData to point to that newly allocated object ptrToData = RuntimeImports.RhNewObject(pEEType); Entry entry = LookupInCache(s_cache, pEETypePtr, pEETypePtr); if (entry == null) { entry = CacheMiss(pEETypePtr, pEETypePtr, SignatureKind.DefaultConstructor); } RawCalliHelper.Call(entry.Result, ptrToData); }
private static unsafe Entry CacheMiss(IntPtr context, IntPtr signature, SignatureKind signatureKind = SignatureKind.GenericDictionary, object contextObject = null) { IntPtr result = IntPtr.Zero, auxResult = IntPtr.Zero; bool previouslyCached = false; // // Try to find the entry in the previous version of the cache that is kept alive by weak reference // if (s_previousCache.IsAllocated) { Entry[] previousCache = (Entry[])s_previousCache.Target; if (previousCache != null) { Entry previousEntry = LookupInCache(previousCache, context, signature); if (previousEntry != null) { result = previousEntry.Result; auxResult = previousEntry.AuxResult; previouslyCached = true; } } } // // Call into the type loader to compute the target // if (!previouslyCached) { switch (signatureKind) { case SignatureKind.GenericDictionary: result = RuntimeAugments.TypeLoaderCallbacks.GenericLookupFromContextAndSignature(context, signature, out auxResult); break; case SignatureKind.GenericVirtualMethod: result = Internal.Runtime.CompilerServices.GenericVirtualMethodSupport.GVMLookupForSlot(new RuntimeTypeHandle(new EETypePtr(context)), *(RuntimeMethodHandle *)&signature); break; case SignatureKind.OpenInstanceResolver: result = Internal.Runtime.CompilerServices.OpenMethodResolver.ResolveMethodWorker(signature, contextObject); break; case SignatureKind.DefaultConstructor: { result = RuntimeAugments.TypeLoaderCallbacks.TryGetDefaultConstructorForType(new RuntimeTypeHandle(new EETypePtr(context))); if (result == IntPtr.Zero) { result = RuntimeAugments.GetFallbackDefaultConstructor(); } } break; case SignatureKind.GenericDelegateThunk: result = RuntimeAugments.TypeLoaderCallbacks.GetDelegateThunk((Delegate)contextObject, (int)signature); break; default: result = RawCalliHelper.Call <IntPtr>(s_resolutionFunctionPointers[(int)signatureKind], context, signature, contextObject, out auxResult); break; } } // // Update the cache under the lock // if (s_lock == null) { Interlocked.CompareExchange(ref s_lock, new Lock(), null); } s_lock.Acquire(); try { // Avoid duplicate entries Entry existingEntry = LookupInCache(s_cache, context, signature); if (existingEntry != null) { return(existingEntry); } // Resize cache as necessary Entry[] cache = ResizeCacheForNewEntryAsNecessary(); int key = ((context.GetHashCode() >> 4) ^ signature.GetHashCode()) & (cache.Length - 1); Entry newEntry = new Entry() { Context = context, Signature = signature, Result = result, AuxResult = auxResult, Next = cache[key] }; cache[key] = newEntry; return(newEntry); } finally { s_lock.Release(); } }
public unsafe static int InvokeExeMain(IntPtr pfnUserMain) { string[] commandLine = InternalCreateCommandLine(); return(RawCalliHelper.Call <int>(pfnUserMain, commandLine)); }