Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -286,25 +286,32 @@ private ILEmitResolverBuilderRuntimeContext GenerateMethodBody(ServiceCallSite c

// if (scope.IsRootScope)
// {
// return CallSiteRuntimeResolver.Instance.Resolve(callSite, scope);
// return CallSiteRuntimeResolver.Instance.Resolve(callSite, scope);
// }
// var cacheKey = scopedCallSite.CacheKey;
// try
// {
// var cacheKey = scopedCallSite.CacheKey;
// object sync;
// bool lockTaken;
// object result;
// try
// {
// var resolvedServices = scope.ResolvedServices;
// Monitor.Enter(resolvedServices, out var lockTaken);
// if (!resolvedServices.TryGetValue(cacheKey, out value)
// sync = scope.Sync;
// Monitor.Enter(sync, ref lockTaken);
// if (!resolvedServices.TryGetValue(cacheKey, out result)
// {
// value = [createvalue];
// CaptureDisposable(value);
// resolvedServices.Add(cacheKey, value);
// result = [createvalue];
// CaptureDisposable(result);
// resolvedServices.Add(cacheKey, result);
// }
// }
// finally
// {
// if (lockTaken) Monitor.Exit(scope.ResolvedServices);
// if (lockTaken)
// {
// Monitor.Exit(sync);
// }
// }
// return value;
// return result;

if (callSite.Cache.Location == CallSiteResultCacheLocation.Scope)
{
Expand Down Expand Up @@ -333,7 +340,7 @@ private ILEmitResolverBuilderRuntimeContext GenerateMethodBody(ServiceCallSite c
context.Generator.MarkLabel(defaultLabel);
AddCacheKey(context, callSite.Cache.Key);
// and store to local
Stloc(context.Generator, cacheKeyLocal.LocalIndex);
context.Generator.Emit(OpCodes.Stloc, cacheKeyLocal);

context.Generator.BeginExceptionBlock();

Expand All @@ -342,28 +349,28 @@ private ILEmitResolverBuilderRuntimeContext GenerateMethodBody(ServiceCallSite c
// .ResolvedServices
context.Generator.Emit(OpCodes.Callvirt, ResolvedServicesGetter);
// Store resolved services
Stloc(context.Generator, resolvedServicesLocal.LocalIndex);
context.Generator.Emit(OpCodes.Stloc, resolvedServicesLocal);

// scope
context.Generator.Emit(OpCodes.Ldarg_1);
// .Sync
context.Generator.Emit(OpCodes.Callvirt, ScopeLockGetter);
// Store syncLocal
Stloc(context.Generator, syncLocal.LocalIndex);
context.Generator.Emit(OpCodes.Stloc, syncLocal);

// Load syncLocal
Ldloc(context.Generator, syncLocal.LocalIndex);
context.Generator.Emit(OpCodes.Ldloc, syncLocal);
// Load address of lockTaken
context.Generator.Emit(OpCodes.Ldloca_S, lockTakenLocal.LocalIndex);
context.Generator.Emit(OpCodes.Ldloca, lockTakenLocal);
// Monitor.Enter
context.Generator.Emit(OpCodes.Call, ServiceLookupHelpers.MonitorEnterMethodInfo);

// Load resolved services
Ldloc(context.Generator, resolvedServicesLocal.LocalIndex);
context.Generator.Emit(OpCodes.Ldloc, resolvedServicesLocal);
// Load cache key
Ldloc(context.Generator, cacheKeyLocal.LocalIndex);
context.Generator.Emit(OpCodes.Ldloc, cacheKeyLocal);
// Load address of result local
context.Generator.Emit(OpCodes.Ldloca_S, resultLocal.LocalIndex);
context.Generator.Emit(OpCodes.Ldloca, resultLocal);
// .TryGetValue
context.Generator.Emit(OpCodes.Callvirt, ServiceLookupHelpers.TryGetValueMethodInfo);

Expand All @@ -372,23 +379,23 @@ private ILEmitResolverBuilderRuntimeContext GenerateMethodBody(ServiceCallSite c

// Create value
VisitCallSiteMain(callSite, context);
Stloc(context.Generator, resultLocal.LocalIndex);
context.Generator.Emit(OpCodes.Stloc, resultLocal);

if (callSite.CaptureDisposable)
{
BeginCaptureDisposable(context);
Ldloc(context.Generator, resultLocal.LocalIndex);
context.Generator.Emit(OpCodes.Ldloc, resultLocal);
EndCaptureDisposable(context);
// Pop value returned by CaptureDisposable off the stack
generator.Emit(OpCodes.Pop);
}

// load resolvedServices
Ldloc(context.Generator, resolvedServicesLocal.LocalIndex);
context.Generator.Emit(OpCodes.Ldloc, resolvedServicesLocal);
// load cache key
Ldloc(context.Generator, cacheKeyLocal.LocalIndex);
context.Generator.Emit(OpCodes.Ldloc, cacheKeyLocal);
// load value
Ldloc(context.Generator, resultLocal.LocalIndex);
context.Generator.Emit(OpCodes.Ldloc, resultLocal);
// .Add
context.Generator.Emit(OpCodes.Callvirt, ServiceLookupHelpers.AddMethodInfo);

Expand All @@ -397,21 +404,20 @@ private ILEmitResolverBuilderRuntimeContext GenerateMethodBody(ServiceCallSite c
context.Generator.BeginFinallyBlock();

// load lockTaken
Ldloc(context.Generator, lockTakenLocal.LocalIndex);
context.Generator.Emit(OpCodes.Ldloc, lockTakenLocal);
// return if not
context.Generator.Emit(OpCodes.Brfalse, returnLabel);
// Load syncLocal
Ldloc(context.Generator, syncLocal.LocalIndex);
context.Generator.Emit(OpCodes.Ldloc, syncLocal);
// Monitor.Exit
context.Generator.Emit(OpCodes.Call, ServiceLookupHelpers.MonitorExitMethodInfo);

context.Generator.MarkLabel(returnLabel);

context.Generator.EndExceptionBlock();


// load value
Ldloc(context.Generator, resultLocal.LocalIndex);
context.Generator.Emit(OpCodes.Ldloc, resultLocal);
// return
context.Generator.Emit(OpCodes.Ret);
}
Expand All @@ -436,54 +442,8 @@ private static void BeginCaptureDisposable(ILEmitResolverBuilderContext argument

private static void EndCaptureDisposable(ILEmitResolverBuilderContext argument)
{
// Call CaptureDisposabl we expect calee and arguments to be on the stackcontext.Generator.BeginExceptionBlock
// When calling CaptureDisposable we expect callee and arguments to be on the stackcontext.Generator.BeginExceptionBlock
argument.Generator.Emit(OpCodes.Callvirt, ServiceLookupHelpers.CaptureDisposableMethodInfo);
}

private void Ldloc(ILGenerator generator, int index)
{
switch (index)
{
case 0: generator.Emit(OpCodes.Ldloc_0);
return;
case 1: generator.Emit(OpCodes.Ldloc_1);
return;
case 2: generator.Emit(OpCodes.Ldloc_2);
return;
case 3: generator.Emit(OpCodes.Ldloc_3);
return;
}

if (index < byte.MaxValue)
{
generator.Emit(OpCodes.Ldloc_S, (byte)index);
return;
}

generator.Emit(OpCodes.Ldloc, index);
}

private void Stloc(ILGenerator generator, int index)
{
switch (index)
{
case 0: generator.Emit(OpCodes.Stloc_0);
return;
case 1: generator.Emit(OpCodes.Stloc_1);
return;
case 2: generator.Emit(OpCodes.Stloc_2);
return;
case 3: generator.Emit(OpCodes.Stloc_3);
return;
}

if (index < byte.MaxValue)
{
generator.Emit(OpCodes.Stloc_S, (byte)index);
return;
}

generator.Emit(OpCodes.Stloc, index);
}
}
}