protected override void EmitCode(NodeFactory factory, ref X86Emitter instructionEncoder, bool relocsOnly) { switch (_thunkKind) { case Kind.Eager: break; case Kind.DelayLoadHelper: case Kind.VirtualStubDispatch: instructionEncoder.EmitXOR(Register.EAX, Register.EAX); if (!relocsOnly) { // push table index instructionEncoder.EmitPUSH((sbyte)_instanceCell.Table.IndexFromBeginningOfArray); } // push [module] instructionEncoder.EmitPUSH(_moduleImport); break; case Kind.Lazy: // mov edx, [module] instructionEncoder.EmitMOV(Register.EDX, _moduleImport); break; } instructionEncoder.EmitJMP(_helperCell); }
protected override void EmitCode(NodeFactory factory, ref X86Emitter instructionEncoder, bool relocsOnly) { switch (_thunkKind) { case Kind.Eager: break; case Kind.DelayLoadHelper: case Kind.VirtualStubDispatch: instructionEncoder.EmitXOR(Register.EAX, Register.EAX); if (!relocsOnly) { // push table index instructionEncoder.EmitPUSH((sbyte)_containingImportSection.IndexFromBeginningOfArray); } // push [module] instructionEncoder.EmitPUSH(factory.ModuleImport); break; case Kind.Lazy: // mov edx, [module] instructionEncoder.EmitMOV(Register.EDX, factory.ModuleImport); break; default: throw new NotSupportedException(_thunkKind.ToString() + " is not supported"); } instructionEncoder.EmitJMP(_helperCell); }
protected override void EmitCode(NodeFactory factory, ref X86Emitter encoder, bool relocsOnly) { switch (Id) { case ReadyToRunHelperId.VirtualCall: { encoder.EmitINT3(); } break; case ReadyToRunHelperId.GetNonGCStaticBase: { MetadataType target = (MetadataType)Target; bool hasLazyStaticConstructor = factory.TypeSystemContext.HasLazyStaticConstructor(target); encoder.EmitMOV(encoder.TargetRegister.Result, factory.TypeNonGCStaticsSymbol(target)); if (!hasLazyStaticConstructor) { encoder.EmitRET(); } else { // We need to trigger the cctor before returning the base. It is stored at the beginning of the non-GC statics region. encoder.EmitMOV(encoder.TargetRegister.Arg0, factory.TypeNonGCStaticsSymbol(target), -NonGCStaticsNode.GetClassConstructorContextStorageSize(factory.Target, target)); AddrMode initialized = new AddrMode(encoder.TargetRegister.Arg0, null, factory.Target.PointerSize, 0, AddrModeSize.Int32); encoder.EmitCMP(ref initialized, 1); encoder.EmitRETIfEqual(); encoder.EmitMOV(encoder.TargetRegister.Arg1, encoder.TargetRegister.Result); encoder.EmitJMP(factory.HelperEntrypoint(HelperEntrypoint.EnsureClassConstructorRunAndReturnNonGCStaticBase)); } } break; case ReadyToRunHelperId.GetThreadStaticBase: { encoder.EmitINT3(); } break; case ReadyToRunHelperId.GetGCStaticBase: { encoder.EmitINT3(); } break; case ReadyToRunHelperId.DelegateCtor: { encoder.EmitINT3(); } break; case ReadyToRunHelperId.ResolveVirtualFunction: { encoder.EmitINT3(); } break; default: throw new NotImplementedException(); } }