本文整理汇总了C#中ILCompiler.DependencyAnalysis.NodeFactory.ConstructedTypeSymbol方法的典型用法代码示例。如果您正苦于以下问题:C# NodeFactory.ConstructedTypeSymbol方法的具体用法?C# NodeFactory.ConstructedTypeSymbol怎么用?C# NodeFactory.ConstructedTypeSymbol使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ILCompiler.DependencyAnalysis.NodeFactory
的用法示例。
在下文中一共展示了NodeFactory.ConstructedTypeSymbol方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: EncodeData
public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
{
dataBuilder.EmitZeroPointer(); // Sync block
DefType systemStringType = factory.TypeSystemContext.GetWellKnownType(WellKnownType.String);
//
// The GC requires a direct reference to frozen objects' EETypes. If System.String will be compiled into a separate
// binary, it must be cloned into this one.
//
if (factory.CompilationModuleGroup.ShouldReferenceThroughImportTable(systemStringType))
{
dataBuilder.EmitPointerReloc(factory.ConstructedClonedTypeSymbol(systemStringType));
}
else
{
dataBuilder.EmitPointerReloc(factory.ConstructedTypeSymbol(systemStringType));
}
dataBuilder.EmitInt(_data.Length);
foreach (char c in _data)
{
dataBuilder.EmitShort((short)c);
}
// Null-terminate for friendliness with interop
dataBuilder.EmitShort(0);
}
示例2: GetData
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
{
// This node does not trigger generation of other nodes.
if (relocsOnly)
return new ObjectData(Array.Empty<byte>(), Array.Empty<Relocation>(), 1, new ISymbolNode[] { this });
ObjectDataBuilder builder = new ObjectDataBuilder(factory);
foreach (var mappingEntry in factory.MetadataManager.GetTypeDefinitionMapping())
{
if (!factory.CompilationModuleGroup.ContainsType(mappingEntry.Entity))
continue;
var node = factory.ConstructedTypeSymbol(mappingEntry.Entity) as EETypeNode;
if (node.Marked)
{
// TODO: this format got very inefficient due to not being able to use RVAs
// replace with a hash table
builder.EmitPointerReloc(node);
builder.EmitInt(mappingEntry.MetadataHandle);
if (factory.Target.PointerSize == 8)
builder.EmitInt(0); // Pad
}
}
_endSymbol.SetSymbolOffset(builder.CountBytes);
builder.DefinedSymbols.Add(this);
builder.DefinedSymbols.Add(_endSymbol);
return builder.ToObjectData();
}
示例3: GetData
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
{
var builder = new ObjectDataBuilder(factory);
// These need to be aligned the same as methods because they show up in same contexts
builder.RequireAlignment(factory.Target.MinimumFunctionAlignment);
builder.DefinedSymbols.Add(this);
MethodDesc canonMethod = Method.GetCanonMethodTarget(CanonicalFormKind.Specific);
// Pointer to the canonical body of the method
builder.EmitPointerReloc(factory.MethodEntrypoint(canonMethod));
// Find out what's the context to use
ISymbolNode contextParameter;
if (canonMethod.RequiresInstMethodDescArg())
{
contextParameter = factory.MethodGenericDictionary(Method);
}
else
{
Debug.Assert(canonMethod.RequiresInstMethodTableArg());
// Ask for a constructed type symbol because we need the vtable to get to the dictionary
contextParameter = factory.ConstructedTypeSymbol(Method.OwningType);
}
// The next entry is a pointer to the pointer to the context to be used for the canonical method
// TODO: in multi-module, this points to the import cell, and is no longer this weird pointer
builder.EmitPointerReloc(factory.Indirection(contextParameter));
return builder.ToObjectData();
}
示例4: ShouldSkipEmittingObjectNode
public override bool ShouldSkipEmittingObjectNode(NodeFactory factory)
{
// If there is a constructed version of this node in the graph, emit that instead
if (ConstructedEETypeNode.CreationAllowed(_type))
return ((DependencyNode)factory.ConstructedTypeSymbol(_type)).Marked;
return false;
}
示例5: ComputeNonRelocationBasedDependencies
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory)
{
DefType closestDefType = _type.GetClosestDefType();
DependencyList dependencyList = new DependencyList();
if (_type.RuntimeInterfaces.Length > 0)
{
dependencyList.Add(factory.InterfaceDispatchMap(_type), "Interface dispatch map");
// If any of the implemented interfaces have variance, calls against compatible interface methods
// could result in interface methods of this type being used (e.g. IEnumberable<object>.GetEnumerator()
// can dispatch to an implementation of IEnumerable<string>.GetEnumerator()).
// For now, we will not try to optimize this and we will pretend all interface methods are necessary.
foreach (var implementedInterface in _type.RuntimeInterfaces)
{
if (implementedInterface.HasVariance)
{
foreach (var interfaceMethod in implementedInterface.GetAllMethods())
{
if (interfaceMethod.Signature.IsStatic)
continue;
MethodDesc implMethod = closestDefType.ResolveInterfaceMethodToVirtualMethodOnType(interfaceMethod);
if (implMethod != null)
{
dependencyList.Add(factory.VirtualMethodUse(interfaceMethod), "Variant interface method");
dependencyList.Add(factory.VirtualMethodUse(implMethod), "Variant interface method");
}
}
}
}
}
if (_type.IsArray)
{
// Array EEType depends on System.Array's virtuals. Array EETypes don't point to
// their base type (i.e. there's no reloc based dependency making this "just work").
dependencyList.Add(factory.ConstructedTypeSymbol(_type.BaseType), "Array base type");
}
dependencyList.Add(factory.VTable(_type), "VTable");
if (closestDefType.HasGenericDictionarySlot())
{
// Generic dictionary pointer is part of the vtable and as such it gets only laid out
// at the final data emission phase. We need to report it as a non-relocation dependency.
dependencyList.Add(factory.TypeGenericDictionary(closestDefType), "Type generic dictionary");
}
// Include the optional fields by default. We don't know if optional fields will be needed until
// all of the interface usage has been stabilized. If we end up not needing it, the EEType node will not
// generate any relocs to it, and the optional fields node will instruct the object writer to skip
// emitting it.
dependencyList.Add(_optionalFieldsNode, "Optional fields");
return dependencyList;
}
示例6: ShouldSkipEmittingObjectNode
public override bool ShouldSkipEmittingObjectNode(NodeFactory factory)
{
if (!_constructed)
{
// If there is a constructed version of this node in the graph, emit that instead
if (((DependencyNode)factory.ConstructedTypeSymbol(_type)).Marked)
{
return true;
}
}
return false;
}
示例7: ReadyToRunHelperNode
public ReadyToRunHelperNode(NodeFactory factory, ReadyToRunHelperId id, Object target)
{
_id = id;
_target = target;
switch (id)
{
case ReadyToRunHelperId.NewHelper:
case ReadyToRunHelperId.NewArr1:
{
// Make sure that if the EEType can't be generated, we throw the exception now.
// This way we can fail generating code for the method that references the EEType
// and (depending on the policy), we could avoid scraping the entire compilation.
TypeDesc type = (TypeDesc)target;
factory.ConstructedTypeSymbol(type);
}
break;
case ReadyToRunHelperId.IsInstanceOf:
case ReadyToRunHelperId.CastClass:
{
// Make sure that if the EEType can't be generated, we throw the exception now.
// This way we can fail generating code for the method that references the EEType
// and (depending on the policy), we could avoid scraping the entire compilation.
TypeDesc type = (TypeDesc)target;
factory.NecessaryTypeSymbol(type);
Debug.Assert(!type.IsNullable, "Nullable needs to be unwrapped");
}
break;
case ReadyToRunHelperId.GetNonGCStaticBase:
case ReadyToRunHelperId.GetGCStaticBase:
case ReadyToRunHelperId.GetThreadStaticBase:
{
// Make sure we can compute static field layout now so we can fail early
DefType defType = (DefType)target;
defType.ComputeStaticFieldLayout(StaticLayoutKind.StaticRegionSizesAndFields);
}
break;
}
}
示例8: ComputeNonRelocationBasedDependencies
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory)
{
DependencyList dependencyList = new DependencyList();
if (_type.RuntimeInterfaces.Length > 0)
{
dependencyList.Add(factory.InterfaceDispatchMap(_type), "Interface dispatch map");
// If any of the implemented interfaces have variance, calls against compatible interface methods
// could result in interface methods of this type being used (e.g. IEnumberable<object>.GetEnumerator()
// can dispatch to an implementation of IEnumerable<string>.GetEnumerator()).
// For now, we will not try to optimize this and we will pretend all interface methods are necessary.
DefType defType = _type.GetClosestDefType();
foreach (var implementedInterface in defType.RuntimeInterfaces)
{
if (implementedInterface.HasVariance)
{
foreach (var interfaceMethod in implementedInterface.GetAllVirtualMethods())
{
MethodDesc implMethod = defType.ResolveInterfaceMethodToVirtualMethodOnType(interfaceMethod);
if (implMethod != null)
{
dependencyList.Add(factory.VirtualMethodUse(interfaceMethod), "Variant interface method");
dependencyList.Add(factory.VirtualMethodUse(implMethod), "Variant interface method");
}
}
}
}
}
if (_type.IsArray)
{
// Array EEType depends on System.Array's virtuals. Array EETypes don't point to
// their base type (i.e. there's no reloc based dependency making this "just work").
dependencyList.Add(factory.ConstructedTypeSymbol(_type.BaseType), "Array base type");
}
dependencyList.Add(factory.VTable(_type), "VTable");
return dependencyList;
}
示例9: GetBaseTypeNode
protected override ISymbolNode GetBaseTypeNode(NodeFactory factory)
{
return _type.BaseType != null ? factory.ConstructedTypeSymbol(_type.BaseType) : null;
}
示例10: EmitCode
protected override void EmitCode(NodeFactory factory, ref X64Emitter encoder, bool relocsOnly)
{
switch (Id)
{
case ReadyToRunHelperId.NewHelper:
encoder.EmitLEAQ(encoder.TargetRegister.Arg0, factory.ConstructedTypeSymbol((TypeDesc)Target));
encoder.EmitJMP(factory.ExternSymbol("__allocate_object"));
break;
case ReadyToRunHelperId.VirtualCall:
if (relocsOnly)
break;
AddrMode loadFromThisPtr = new AddrMode(encoder.TargetRegister.Arg0, null, 0, 0, AddrModeSize.Int64);
encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromThisPtr);
{
int slot = VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, (MethodDesc)Target);
Debug.Assert(slot != -1);
AddrMode jmpAddrMode = new AddrMode(encoder.TargetRegister.Result, null, EETypeNode.GetVTableOffset(factory.Target.PointerSize) + (slot * factory.Target.PointerSize), 0, AddrModeSize.Int64);
encoder.EmitJmpToAddrMode(ref jmpAddrMode);
}
break;
case ReadyToRunHelperId.IsInstanceOf:
encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.NecessaryTypeSymbol((TypeDesc)Target));
encoder.EmitJMP(factory.ExternSymbol("__isinst_class"));
break;
case ReadyToRunHelperId.CastClass:
encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.NecessaryTypeSymbol((TypeDesc)Target));
encoder.EmitJMP(factory.ExternSymbol("__castclass_class"));
break;
case ReadyToRunHelperId.NewArr1:
encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.NecessaryTypeSymbol((TypeDesc)Target));
encoder.EmitJMP(factory.ExternSymbol("__allocate_array"));
break;
case ReadyToRunHelperId.GetNonGCStaticBase:
if (!((MetadataType)Target).HasStaticConstructor)
{
Debug.Assert(Id == ReadyToRunHelperId.GetNonGCStaticBase);
encoder.EmitLEAQ(encoder.TargetRegister.Result, factory.TypeNonGCStaticsSymbol((MetadataType)Target));
encoder.EmitRET();
}
else
{
// We need to trigger the cctor before returning the base
encoder.EmitLEAQ(encoder.TargetRegister.Arg0, factory.TypeCctorContextSymbol((MetadataType)Target));
encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.TypeNonGCStaticsSymbol((MetadataType)Target));
encoder.EmitJMP(factory.HelperEntrypoint(HelperEntrypoint.EnsureClassConstructorRunAndReturnNonGCStaticBase));
}
break;
case ReadyToRunHelperId.GetThreadStaticBase:
encoder.EmitINT3();
break;
case ReadyToRunHelperId.GetGCStaticBase:
if (!((MetadataType)Target).HasStaticConstructor)
{
encoder.EmitLEAQ(encoder.TargetRegister.Result, factory.TypeGCStaticsSymbol((MetadataType)Target));
AddrMode loadFromRax = new AddrMode(encoder.TargetRegister.Result, null, 0, 0, AddrModeSize.Int64);
encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromRax);
encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromRax);
encoder.EmitRET();
}
else
{
// We need to trigger the cctor before returning the base
encoder.EmitLEAQ(encoder.TargetRegister.Arg0, factory.TypeCctorContextSymbol((MetadataType)Target));
encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.TypeGCStaticsSymbol((MetadataType)Target));
AddrMode loadFromRdx = new AddrMode(encoder.TargetRegister.Arg1, null, 0, 0, AddrModeSize.Int64);
encoder.EmitMOV(encoder.TargetRegister.Arg1, ref loadFromRdx);
encoder.EmitMOV(encoder.TargetRegister.Arg1, ref loadFromRdx);
encoder.EmitJMP(factory.HelperEntrypoint(HelperEntrypoint.EnsureClassConstructorRunAndReturnGCStaticBase));
}
break;
case ReadyToRunHelperId.DelegateCtor:
{
DelegateInfo target = (DelegateInfo)Target;
encoder.EmitLEAQ(encoder.TargetRegister.Arg2, factory.MethodEntrypoint(target.Target));
if (target.ShuffleThunk != null)
encoder.EmitLEAQ(encoder.TargetRegister.Arg3, factory.MethodEntrypoint(target.ShuffleThunk));
encoder.EmitJMP(factory.MethodEntrypoint(target.Ctor));
}
break;
default:
throw new NotImplementedException();
}
}
示例11: GetData
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
{
// This node does not trigger generation of other nodes.
if (relocsOnly)
return new ObjectData(Array.Empty<byte>(), Array.Empty<Relocation>(), 1, new ISymbolNode[] { this });
ObjectDataBuilder builder = new ObjectDataBuilder(factory);
foreach (var mappingEntry in factory.MetadataManager.GetTypeDefinitionMapping())
{
if (!factory.CompilationModuleGroup.ContainsType(mappingEntry.Entity))
continue;
// We are looking for any EEType - constructed or not, it has to be in the mapping
// table so that we can map it to metadata.
EETypeNode node = null;
if (!mappingEntry.Entity.IsGenericDefinition)
{
node = factory.ConstructedTypeSymbol(mappingEntry.Entity) as EETypeNode;
}
if (node == null || !node.Marked)
{
// This might have been a typeof() expression.
node = factory.NecessaryTypeSymbol(mappingEntry.Entity) as EETypeNode;
}
if (node.Marked)
{
// TODO: this format got very inefficient due to not being able to use RVAs
// replace with a hash table
builder.EmitPointerReloc(node);
builder.EmitInt(mappingEntry.MetadataHandle);
if (factory.Target.PointerSize == 8)
builder.EmitInt(0); // Pad
}
}
_endSymbol.SetSymbolOffset(builder.CountBytes);
builder.DefinedSymbols.Add(this);
builder.DefinedSymbols.Add(_endSymbol);
return builder.ToObjectData();
}
示例12: EmitCode
protected override void EmitCode(NodeFactory factory, ref X64Emitter encoder, bool relocsOnly)
{
switch (Id)
{
case ReadyToRunHelperId.NewHelper:
{
TypeDesc target = (TypeDesc)Target;
encoder.EmitLEAQ(encoder.TargetRegister.Arg0, factory.ConstructedTypeSymbol(target));
encoder.EmitJMP(factory.ExternSymbol(JitHelper.GetNewObjectHelperForType(target)));
}
break;
case ReadyToRunHelperId.VirtualCall:
if (relocsOnly)
break;
AddrMode loadFromThisPtr = new AddrMode(encoder.TargetRegister.Arg0, null, 0, 0, AddrModeSize.Int64);
encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromThisPtr);
{
int slot = VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, (MethodDesc)Target);
Debug.Assert(slot != -1);
AddrMode jmpAddrMode = new AddrMode(encoder.TargetRegister.Result, null, EETypeNode.GetVTableOffset(factory.Target.PointerSize) + (slot * factory.Target.PointerSize), 0, AddrModeSize.Int64);
encoder.EmitJmpToAddrMode(ref jmpAddrMode);
}
break;
case ReadyToRunHelperId.IsInstanceOf:
{
TypeDesc target = (TypeDesc)Target;
encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.NecessaryTypeSymbol(target));
encoder.EmitJMP(factory.ExternSymbol(JitHelper.GetCastingHelperNameForType(target, false)));
}
break;
case ReadyToRunHelperId.CastClass:
{
TypeDesc target = (TypeDesc)Target;
encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.NecessaryTypeSymbol(target));
encoder.EmitJMP(factory.ExternSymbol(JitHelper.GetCastingHelperNameForType(target, true)));
}
break;
case ReadyToRunHelperId.NewArr1:
{
TypeDesc target = (TypeDesc)Target;
// TODO: Swap argument order instead
// mov arg1, arg0
encoder.Builder.EmitByte(0x48);
encoder.Builder.EmitShort((short)((encoder.TargetRegister.Arg0 == Register.RCX) ? 0xD18B : 0xF78B));
encoder.EmitLEAQ(encoder.TargetRegister.Arg0, factory.NecessaryTypeSymbol(target));
encoder.EmitJMP(factory.ExternSymbol(JitHelper.GetNewArrayHelperForType(target)));
}
break;
case ReadyToRunHelperId.GetNonGCStaticBase:
{
MetadataType target = (MetadataType)Target;
if (!target.HasStaticConstructor)
{
Debug.Assert(Id == ReadyToRunHelperId.GetNonGCStaticBase);
encoder.EmitLEAQ(encoder.TargetRegister.Result, factory.TypeNonGCStaticsSymbol(target));
encoder.EmitRET();
}
else
{
// We need to trigger the cctor before returning the base
encoder.EmitLEAQ(encoder.TargetRegister.Arg0, factory.TypeCctorContextSymbol(target));
encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.TypeNonGCStaticsSymbol(target));
encoder.EmitJMP(factory.HelperEntrypoint(HelperEntrypoint.EnsureClassConstructorRunAndReturnNonGCStaticBase));
}
}
break;
case ReadyToRunHelperId.GetThreadStaticBase:
encoder.EmitINT3();
break;
case ReadyToRunHelperId.GetGCStaticBase:
{
MetadataType target = (MetadataType)Target;
if (!target.HasStaticConstructor)
{
encoder.EmitLEAQ(encoder.TargetRegister.Result, factory.TypeGCStaticsSymbol(target));
AddrMode loadFromRax = new AddrMode(encoder.TargetRegister.Result, null, 0, 0, AddrModeSize.Int64);
encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromRax);
encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromRax);
encoder.EmitRET();
}
else
{
// We need to trigger the cctor before returning the base
encoder.EmitLEAQ(encoder.TargetRegister.Arg0, factory.TypeCctorContextSymbol(target));
encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.TypeGCStaticsSymbol(target));
AddrMode loadFromRdx = new AddrMode(encoder.TargetRegister.Arg1, null, 0, 0, AddrModeSize.Int64);
encoder.EmitMOV(encoder.TargetRegister.Arg1, ref loadFromRdx);
encoder.EmitMOV(encoder.TargetRegister.Arg1, ref loadFromRdx);
//.........这里部分代码省略.........
示例13: OutputRelatedType
private void OutputRelatedType(NodeFactory factory, ref ObjectDataBuilder objData)
{
ISymbolNode relatedTypeNode = null;
if (_type.IsArray || _type.IsPointer)
{
var parameterType = ((ParameterizedType)_type).ParameterType;
relatedTypeNode = factory.NecessaryTypeSymbol(parameterType);
}
else
{
TypeDesc baseType = _type.BaseType;
if (baseType != null)
{
if (_constructed)
{
relatedTypeNode = factory.ConstructedTypeSymbol(baseType);
}
else
{
relatedTypeNode = factory.NecessaryTypeSymbol(baseType);
}
}
}
if (relatedTypeNode != null)
{
objData.EmitPointerReloc(relatedTypeNode);
}
else
{
objData.EmitZeroPointer();
}
}
示例14: GetData
public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
{
ObjectDataBuilder objData = new ObjectDataBuilder(factory);
objData.Alignment = 16;
objData.DefinedSymbols.Add(this);
if (_type.IsArray)
{
objData.EmitShort((short)((ArrayType)_type).ElementType.GetElementSize()); // m_ComponentSize
objData.EmitShort(0x4); // m_flags: IsArray(0x4)
}
else if (_type.IsString)
{
objData.EmitShort(2); // m_ComponentSize
objData.EmitShort(0); // m_flags: 0
}
else
{
objData.EmitShort(0); // m_ComponentSize
objData.EmitShort(0); // m_flags: 0
}
int pointerSize = _type.Context.Target.PointerSize;
int minimumObjectSize = pointerSize * 3;
int objectSize;
if (_type is MetadataType)
{
objectSize = pointerSize +
((MetadataType)_type).InstanceByteCount; // +pointerSize for SyncBlock
}
else if (_type is ArrayType)
{
objectSize = 3 * pointerSize; // SyncBlock + EETypePtr + Length
int rank = ((ArrayType)_type).Rank;
if (rank > 1)
objectSize +=
2 * _type.Context.GetWellKnownType(WellKnownType.Int32).GetElementSize() * rank;
}
else
throw new NotImplementedException();
objectSize = AlignmentHelper.AlignUp(objectSize, pointerSize);
objectSize = Math.Max(minimumObjectSize, objectSize);
if (_type.IsString)
{
// If this is a string, throw away objectSize we computed so far. Strings are special.
// SyncBlock + EETypePtr + length + firstChar
objectSize = 2 * pointerSize +
_type.Context.GetWellKnownType(WellKnownType.Int32).GetElementSize() +
_type.Context.GetWellKnownType(WellKnownType.Char).GetElementSize();
}
objData.EmitInt(objectSize);
if (Type.BaseType != null)
{
if (_constructed)
{
objData.EmitPointerReloc(factory.ConstructedTypeSymbol(Type.BaseType));
}
else
{
objData.EmitPointerReloc(factory.NecessaryTypeSymbol(Type.BaseType));
}
}
else
{
objData.EmitZeroPointer();
}
if (_constructed)
{
OutputVirtualSlots(ref objData, _type, _type, factory);
}
return objData.ToObjectData();
}
示例15: EmitCode
protected override void EmitCode(NodeFactory factory, ref X64Emitter encoder, bool relocsOnly)
{
switch (Id)
{
case ReadyToRunHelperId.NewHelper:
encoder.EmitLEAQ(encoder.TargetRegister.Arg0, factory.ConstructedTypeSymbol((TypeDesc)Target));
encoder.EmitJMP(factory.ExternSymbol("__allocate_object"));
break;
case ReadyToRunHelperId.VirtualCall:
if (relocsOnly)
break;
AddrMode loadFromRcx = new AddrMode(encoder.TargetRegister.Arg0, null, 0, 0, AddrModeSize.Int64);
encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromRcx);
// TODO: More efficient lookup of the slot
{
MethodDesc method = (MethodDesc)Target;
TypeDesc owningType = method.OwningType;
int baseSlots = 0;
var baseType = owningType.BaseType;
while (baseType != null)
{
List<MethodDesc> baseVirtualSlots;
factory.VirtualSlots.TryGetValue(baseType, out baseVirtualSlots);
if (baseVirtualSlots != null)
baseSlots += baseVirtualSlots.Count;
baseType = baseType.BaseType;
}
List<MethodDesc> virtualSlots = factory.VirtualSlots[owningType];
int methodSlot = -1;
for (int slot = 0; slot < virtualSlots.Count; slot++)
{
if (virtualSlots[slot] == method)
{
methodSlot = slot;
break;
}
}
Debug.Assert(methodSlot != -1);
AddrMode jmpAddrMode = new AddrMode(encoder.TargetRegister.Result, null, 16 + (baseSlots + methodSlot) * factory.Target.PointerSize, 0, AddrModeSize.Int64);
encoder.EmitJmpToAddrMode(ref jmpAddrMode);
}
break;
case ReadyToRunHelperId.IsInstanceOf:
encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.NecessaryTypeSymbol((TypeDesc)Target));
encoder.EmitJMP(factory.ExternSymbol("__isinst_class"));
break;
case ReadyToRunHelperId.CastClass:
encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.NecessaryTypeSymbol((TypeDesc)Target));
encoder.EmitJMP(factory.ExternSymbol("__castclass_class"));
break;
case ReadyToRunHelperId.NewArr1:
encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.NecessaryTypeSymbol((TypeDesc)Target));
encoder.EmitJMP(factory.ExternSymbol("__allocate_array"));
break;
case ReadyToRunHelperId.GetNonGCStaticBase:
if (!((MetadataType)Target).HasStaticConstructor)
{
Debug.Assert(Id == ReadyToRunHelperId.GetNonGCStaticBase);
encoder.EmitLEAQ(encoder.TargetRegister.Result, factory.TypeNonGCStaticsSymbol((MetadataType)Target));
encoder.EmitRET();
}
else
{
// We need to trigger the cctor before returning the base
encoder.EmitLEAQ(encoder.TargetRegister.Arg0, factory.TypeCctorContextSymbol((MetadataType)Target));
encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.TypeNonGCStaticsSymbol((MetadataType)Target));
encoder.EmitJMP(factory.HelperEntrypoint(HelperEntrypoint.EnsureClassConstructorRunAndReturnNonGCStaticBase));
}
break;
case ReadyToRunHelperId.GetThreadStaticBase:
encoder.EmitINT3();
break;
case ReadyToRunHelperId.GetGCStaticBase:
if (!((MetadataType)Target).HasStaticConstructor)
{
encoder.EmitLEAQ(encoder.TargetRegister.Result, factory.TypeGCStaticsSymbol((MetadataType)Target));
AddrMode loadFromRax = new AddrMode(encoder.TargetRegister.Result, null, 0, 0, AddrModeSize.Int64);
encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromRax);
encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromRax);
encoder.EmitRET();
}
else
{
// We need to trigger the cctor before returning the base
encoder.EmitLEAQ(encoder.TargetRegister.Arg0, factory.TypeCctorContextSymbol((MetadataType)Target));
encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.TypeGCStaticsSymbol((MetadataType)Target));
//.........这里部分代码省略.........