// // // Token resolution calls // // public override void Emit(OpCode opcode, MethodInfo meth) { ArgumentNullException.ThrowIfNull(meth); int stackchange = 0; int token; DynamicMethod?dynMeth = meth as DynamicMethod; if (dynMeth == null) { RuntimeMethodInfo?rtMeth = meth as RuntimeMethodInfo; if (rtMeth == null) { throw new ArgumentException(SR.Argument_MustBeRuntimeMethodInfo, nameof(meth)); } RuntimeType declaringType = rtMeth.GetRuntimeType(); if (declaringType != null && (declaringType.IsGenericType || declaringType.IsArray)) { token = GetTokenFor(rtMeth, declaringType); } else { token = GetTokenFor(rtMeth); } } else { // rule out not allowed operations on DynamicMethods if (opcode.Equals(OpCodes.Ldtoken) || opcode.Equals(OpCodes.Ldftn) || opcode.Equals(OpCodes.Ldvirtftn)) { throw new ArgumentException(SR.Argument_InvalidOpCodeOnDynamicMethod); } token = GetTokenFor(dynMeth); } EnsureCapacity(7); InternalEmit(opcode); if (opcode.StackBehaviourPush == StackBehaviour.Varpush && meth.ReturnType != typeof(void)) { stackchange++; } if (opcode.StackBehaviourPop == StackBehaviour.Varpop) { stackchange -= meth.GetParametersNoCopy().Length; } // Pop the "this" parameter if the method is non-static, // and the instruction is not newobj/ldtoken/ldftn. if (!meth.IsStatic && !(opcode.Equals(OpCodes.Newobj) || opcode.Equals(OpCodes.Ldtoken) || opcode.Equals(OpCodes.Ldftn))) { stackchange--; } UpdateStackSize(opcode, stackchange); PutInteger4(token); }
public override void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[] optionalParameterTypes) { if (methodInfo == null) { throw new ArgumentNullException(nameof(methodInfo)); } if (!(opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt) || opcode.Equals(OpCodes.Newobj))) { throw new ArgumentException(SR.Argument_NotMethodCallOpcode, nameof(opcode)); } if (methodInfo.ContainsGenericParameters) { throw new ArgumentException(SR.Argument_GenericsInvalid, nameof(methodInfo)); } if (methodInfo.DeclaringType != null && methodInfo.DeclaringType.ContainsGenericParameters) { throw new ArgumentException(SR.Argument_GenericsInvalid, nameof(methodInfo)); } Contract.EndContractBlock(); int tk; int stackchange = 0; tk = GetMemberRefToken(methodInfo, optionalParameterTypes); EnsureCapacity(7); InternalEmit(opcode); // Push the return value if there is one. if (methodInfo.ReturnType != typeof(void)) { stackchange++; } // Pop the parameters. stackchange -= methodInfo.GetParameterTypes().Length; // Pop the this parameter if the method is non-static and the // instruction is not newobj. if (!(methodInfo is SymbolMethod) && methodInfo.IsStatic == false && !(opcode.Equals(OpCodes.Newobj))) { stackchange--; } // Pop the optional parameters off the stack. if (optionalParameterTypes != null) { stackchange -= optionalParameterTypes.Length; } UpdateStackSize(opcode, stackchange); PutInteger4(tk); }
public override void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[] optionalParameterTypes) { int tk; int stackchange = 0; if (methodInfo == null) { throw new ArgumentNullException("methodInfo"); } if (methodInfo.ContainsGenericParameters) { throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "methodInfo"); } if (methodInfo.DeclaringType != null && methodInfo.DeclaringType.ContainsGenericParameters) { throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "methodInfo"); } tk = GetMemberRefToken(methodInfo, optionalParameterTypes); EnsureCapacity(7); InternalEmit(opcode); // The opcode must be one of call, callvirt, or newobj. BCLDebug.Assert(opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt) || opcode.Equals(OpCodes.Newobj), "Unexpected opcode passed to EmitCall."); // Push the return value if there is one. if (methodInfo.ReturnType != typeof(void)) { stackchange++; } // Pop the parameters. stackchange -= methodInfo.GetParameterTypes().Length; // Pop the this parameter if the method is non-static and the // instruction is not newobj. if (!(methodInfo is SymbolMethod) && methodInfo.IsStatic == false && !(opcode.Equals(OpCodes.Newobj))) { stackchange--; } // Pop the optional parameters off the stack. if (optionalParameterTypes != null) { stackchange -= optionalParameterTypes.Length; } UpdateStackSize(opcode, stackchange); m_length = PutInteger4(tk, m_length, m_ILStream); }
public override void Emit(OpCode opcode, MethodInfo meth) { if (meth == null) { throw new ArgumentNullException("meth"); } int num = 0; DynamicMethod dynamicMethod = meth as DynamicMethod; int tokenFor; if (dynamicMethod == null) { RuntimeMethodInfo runtimeMethodInfo = meth as RuntimeMethodInfo; if (runtimeMethodInfo == null) { throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "meth"); } RuntimeType runtimeType = runtimeMethodInfo.GetRuntimeType(); if (runtimeType != null && (runtimeType.IsGenericType || runtimeType.IsArray)) { tokenFor = this.GetTokenFor(runtimeMethodInfo, runtimeType); } else { tokenFor = this.GetTokenFor(runtimeMethodInfo); } } else { if (opcode.Equals(OpCodes.Ldtoken) || opcode.Equals(OpCodes.Ldftn) || opcode.Equals(OpCodes.Ldvirtftn)) { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOpCodeOnDynamicMethod")); } tokenFor = this.GetTokenFor(dynamicMethod); } base.EnsureCapacity(7); base.InternalEmit(opcode); if (opcode.StackBehaviourPush == StackBehaviour.Varpush && meth.ReturnType != typeof(void)) { num++; } if (opcode.StackBehaviourPop == StackBehaviour.Varpop) { num -= meth.GetParametersNoCopy().Length; } if (!meth.IsStatic && !opcode.Equals(OpCodes.Newobj) && !opcode.Equals(OpCodes.Ldtoken) && !opcode.Equals(OpCodes.Ldftn)) { num--; } base.UpdateStackSize(opcode, num); base.PutInteger4(tokenFor); }
public override void Emit(OpCode opcode, MethodInfo meth) { if (meth == null) { throw new ArgumentNullException("meth"); } int stackchange = 0; int tokenFor = 0; DynamicMethod method = meth as DynamicMethod; if (method == null) { if (!(meth is RuntimeMethodInfo)) { throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "meth"); } if ((meth.DeclaringType != null) && (meth.DeclaringType.IsGenericType || meth.DeclaringType.IsArray)) { tokenFor = this.m_scope.GetTokenFor(meth.MethodHandle, meth.DeclaringType.TypeHandle); } else { tokenFor = this.m_scope.GetTokenFor(meth.MethodHandle); } } else { if ((opcode.Equals(OpCodes.Ldtoken) || opcode.Equals(OpCodes.Ldftn)) || opcode.Equals(OpCodes.Ldvirtftn)) { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOpCodeOnDynamicMethod")); } tokenFor = this.m_scope.GetTokenFor(method); } base.EnsureCapacity(7); base.InternalEmit(opcode); if ((opcode.m_push == StackBehaviour.Varpush) && (meth.ReturnType != typeof(void))) { stackchange++; } if (opcode.m_pop == StackBehaviour.Varpop) { stackchange -= meth.GetParametersNoCopy().Length; } if ((!meth.IsStatic && !opcode.Equals(OpCodes.Newobj)) && (!opcode.Equals(OpCodes.Ldtoken) && !opcode.Equals(OpCodes.Ldftn))) { stackchange--; } base.UpdateStackSize(opcode, stackchange); base.PutInteger4(tokenFor); }
public override void Emit(OpCode opcode, SignatureHelper signature) { if (signature == null) { throw new ArgumentNullException(nameof(signature)); } int stackchange = 0; EnsureCapacity(7); InternalEmit(opcode); // The only IL instruction that has VarPop behaviour, that takes a // Signature token as a parameter is calli. Pop the parameters and // the native function pointer. To be conservative, do not pop the // this pointer since this information is not easily derived from // SignatureHelper. if (opcode.StackBehaviourPop == StackBehaviour.Varpop) { Debug.Assert(opcode.Equals(OpCodes.Calli), "Unexpected opcode encountered for StackBehaviour VarPop."); // Pop the arguments.. stackchange -= signature.ArgumentCount; // Pop native function pointer off the stack. stackchange--; UpdateStackSize(opcode, stackchange); } int token = GetTokenForSig(signature.GetSignature(true)); PutInteger4(token); }
// // // Token resolution calls // // public override void Emit(OpCode opcode, MethodInfo meth) { if (meth == null) throw new ArgumentNullException("meth"); int stackchange = 0; int tempVal = 0; DynamicMethod dynMeth = DynamicMethod.AsDynamicMethod(meth); if (dynMeth == null) { if (!(meth is RuntimeMethodInfo)) throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "meth"); if (meth.DeclaringType != null && (meth.DeclaringType.IsGenericType || meth.DeclaringType.IsArray)) tempVal = m_scope.GetTokenFor(meth.MethodHandle, meth.DeclaringType.TypeHandle); else tempVal = m_scope.GetTokenFor(meth.MethodHandle); } else { // rule out not allowed operations on DynamicMethods if (opcode.Equals(OpCodes.Ldtoken) || opcode.Equals(OpCodes.Ldftn) || opcode.Equals(OpCodes.Ldvirtftn)) { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOpCodeOnDynamicMethod")); } tempVal = m_scope.GetTokenFor(dynMeth); } EnsureCapacity(7); InternalEmit(opcode); if (opcode.m_push == StackBehaviour.Varpush && meth.ReturnType != typeof(void)) { stackchange++; } if (opcode.m_pop == StackBehaviour.Varpop) { stackchange -= meth.GetParametersNoCopy().Length; } // Pop the "this" parameter if the method is non-static, // and the instruction is not newobj/ldtoken/ldftn. if (!meth.IsStatic && !(opcode.Equals(OpCodes.Newobj) || opcode.Equals(OpCodes.Ldtoken) || opcode.Equals(OpCodes.Ldftn))) { stackchange--; } UpdateStackSize(opcode, stackchange); m_length=PutInteger4(tempVal, m_length, m_ILStream); }
public override void Emit(OpCode opcode, MethodInfo meth) { if (meth == (MethodInfo)null) { throw new ArgumentNullException("meth"); } int stackchange = 0; DynamicMethod dm = meth as DynamicMethod; int num; if ((MethodInfo)dm == (MethodInfo)null) { RuntimeMethodInfo rtMeth = meth as RuntimeMethodInfo; if ((MethodInfo)rtMeth == (MethodInfo)null) { throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "meth"); } RuntimeType runtimeType = rtMeth.GetRuntimeType(); num = !(runtimeType != (RuntimeType)null) || !runtimeType.IsGenericType && !runtimeType.IsArray ? this.GetTokenFor(rtMeth) : this.GetTokenFor(rtMeth, runtimeType); } else { if (opcode.Equals(OpCodes.Ldtoken) || opcode.Equals(OpCodes.Ldftn) || opcode.Equals(OpCodes.Ldvirtftn)) { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOpCodeOnDynamicMethod")); } num = this.GetTokenFor(dm); } this.EnsureCapacity(7); this.InternalEmit(opcode); if (opcode.StackBehaviourPush == StackBehaviour.Varpush && meth.ReturnType != typeof(void)) { ++stackchange; } if (opcode.StackBehaviourPop == StackBehaviour.Varpop) { stackchange -= meth.GetParametersNoCopy().Length; } if (!meth.IsStatic && !opcode.Equals(OpCodes.Newobj) && (!opcode.Equals(OpCodes.Ldtoken) && !opcode.Equals(OpCodes.Ldftn))) { --stackchange; } this.UpdateStackSize(opcode, stackchange); this.PutInteger4(num); }
// // // Signature related calls (vararg, calli) // // public override void EmitCalli(OpCode opcode, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Type[] optionalParameterTypes) { int stackchange = 0; SignatureHelper sig; if (optionalParameterTypes != null) { if ((callingConvention & CallingConventions.VarArgs) == 0) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAVarArgCallingConvention")); } } sig = GetMemberRefSignature(callingConvention, returnType, parameterTypes, optionalParameterTypes); EnsureCapacity(7); Emit(OpCodes.Calli); // The opcode passed in must be the calli instruction. BCLDebug.Assert(opcode.Equals(OpCodes.Calli), "Unexpected opcode passed to EmitCalli."); // If there is a non-void return type, push one. if (returnType != typeof(void)) { stackchange++; } // Pop off arguments if any. if (parameterTypes != null) { stackchange -= parameterTypes.Length; } // Pop off vararg arguments. if (optionalParameterTypes != null) { stackchange -= optionalParameterTypes.Length; } // Pop the this parameter if the method has a this parameter. if ((callingConvention & CallingConventions.HasThis) == CallingConventions.HasThis) { stackchange--; } // Pop the native function pointer. stackchange--; UpdateStackSize(opcode, stackchange); int token = AddSignature(sig.GetSignature(true)); m_length = PutInteger4(token, m_length, m_ILStream); }
public override void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[] optionalParameterTypes) { if (methodInfo == (MethodInfo)null) { throw new ArgumentNullException("methodInfo"); } if (!opcode.Equals(OpCodes.Call) && !opcode.Equals(OpCodes.Callvirt) && !opcode.Equals(OpCodes.Newobj)) { throw new ArgumentException(Environment.GetResourceString("Argument_NotMethodCallOpcode"), "opcode"); } if (methodInfo.ContainsGenericParameters) { throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "methodInfo"); } if (methodInfo.DeclaringType != (Type)null && methodInfo.DeclaringType.ContainsGenericParameters) { throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "methodInfo"); } int num = 0; int memberRefToken = this.GetMemberRefToken((MethodBase)methodInfo, optionalParameterTypes); this.EnsureCapacity(7); this.InternalEmit(opcode); if (methodInfo.ReturnType != typeof(void)) { ++num; } int stackchange = num - methodInfo.GetParameterTypes().Length; if (!(methodInfo is SymbolMethod) && !methodInfo.IsStatic && !opcode.Equals(OpCodes.Newobj)) { --stackchange; } if (optionalParameterTypes != null) { stackchange -= optionalParameterTypes.Length; } this.UpdateStackSize(opcode, stackchange); this.PutInteger4(memberRefToken); }
public virtual void Emit(OpCode opcode, MethodInfo meth) { if (meth == null) { throw new ArgumentNullException("meth"); } if ((opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt)) || opcode.Equals(OpCodes.Newobj)) { this.EmitCall(opcode, meth, null); } else { int stackchange = 0; bool useMethodDef = (opcode.Equals(OpCodes.Ldtoken) || opcode.Equals(OpCodes.Ldftn)) || opcode.Equals(OpCodes.Ldvirtftn); int num2 = this.GetMethodToken(meth, null, useMethodDef); this.EnsureCapacity(7); this.InternalEmit(opcode); this.UpdateStackSize(opcode, stackchange); this.RecordTokenFixup(); this.PutInteger4(num2); } }
public override void EmitCalli(OpCode opcode, CallingConvention unmanagedCallConv, Type returnType, Type[] parameterTypes) { int stackchange = 0; int cParams = 0; int i; SignatureHelper sig; // The opcode passed in must be the calli instruction. BCLDebug.Assert(opcode.Equals(OpCodes.Calli), "Unexpected opcode passed to EmitCalli."); if (parameterTypes != null) { cParams = parameterTypes.Length; } sig = SignatureHelper.GetMethodSigHelper(unmanagedCallConv, returnType); if (parameterTypes != null) { for (i = 0; i < cParams; i++) { sig.AddArgument(parameterTypes[i]); } } // If there is a non-void return type, push one. if (returnType != typeof(void)) { stackchange++; } // Pop off arguments if any. if (parameterTypes != null) { stackchange -= cParams; } // Pop the native function pointer. stackchange--; UpdateStackSize(opcode, stackchange); EnsureCapacity(7); Emit(OpCodes.Calli); int token = AddSignature(sig.GetSignature(true)); m_length = PutInteger4(token, m_length, m_ILStream); }
public virtual void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[] optionalParameterTypes) { if (methodInfo == null) { throw new ArgumentNullException("methodInfo"); } if ((!opcode.Equals(OpCodes.Call) && !opcode.Equals(OpCodes.Callvirt)) && !opcode.Equals(OpCodes.Newobj)) { throw new ArgumentException(Environment.GetResourceString("Argument_NotMethodCallOpcode"), "opcode"); } int stackchange = 0; int num2 = this.GetMethodToken(methodInfo, optionalParameterTypes, false); this.EnsureCapacity(7); this.InternalEmit(opcode); if (methodInfo.ReturnType != typeof(void)) { stackchange++; } Type[] parameterTypes = methodInfo.GetParameterTypes(); if (parameterTypes != null) { stackchange -= parameterTypes.Length; } if ((!(methodInfo is SymbolMethod) && !methodInfo.IsStatic) && !opcode.Equals(OpCodes.Newobj)) { stackchange--; } if (optionalParameterTypes != null) { stackchange -= optionalParameterTypes.Length; } this.UpdateStackSize(opcode, stackchange); this.RecordTokenFixup(); this.PutInteger4(num2); }
public virtual void Emit(OpCode opcode, ConstructorInfo con) { if (con == null) throw new ArgumentNullException("con"); Contract.EndContractBlock(); int stackchange = 0; // Constructors cannot be generic so the value of UseMethodDef doesn't matter. int tk = GetMethodToken(con, null, true); EnsureCapacity(7); InternalEmit(opcode); // Make a conservative estimate by assuming a return type and no // this parameter. if (opcode.StackBehaviourPush == StackBehaviour.Varpush) { // Instruction must be one of call or callvirt. Contract.Assert(opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt), "Unexpected opcode encountered for StackBehaviour of VarPush."); stackchange++; } if (opcode.StackBehaviourPop == StackBehaviour.Varpop) { // Instruction must be one of call, callvirt or newobj. Contract.Assert(opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt) || opcode.Equals(OpCodes.Newobj), "Unexpected opcode encountered for StackBehaviour of VarPop."); Type[] parameters = con.GetParameterTypes(); if (parameters != null) stackchange -= parameters.Length; } UpdateStackSize(opcode, stackchange); RecordTokenFixup(); PutInteger4(tk); }
[System.Security.SecuritySafeCritical] // auto-generated public virtual void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[] optionalParameterTypes) { if (methodInfo == null) throw new ArgumentNullException("methodInfo"); if (!(opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt) || opcode.Equals(OpCodes.Newobj))) throw new ArgumentException(Environment.GetResourceString("Argument_NotMethodCallOpcode"), "opcode"); Contract.EndContractBlock(); int stackchange = 0; int tk = GetMethodToken(methodInfo, optionalParameterTypes, false); EnsureCapacity(7); InternalEmit(opcode); // Push the return value if there is one. if (methodInfo.ReturnType != typeof(void)) stackchange++; // Pop the parameters. Type[] parameters = methodInfo.GetParameterTypes(); if (parameters != null) stackchange -= parameters.Length; // Pop the this parameter if the method is non-static and the // instruction is not newobj. if (!(methodInfo is SymbolMethod) && methodInfo.IsStatic == false && !(opcode.Equals(OpCodes.Newobj))) stackchange--; // Pop the optional parameters off the stack. if (optionalParameterTypes != null) stackchange -= optionalParameterTypes.Length; UpdateStackSize(opcode, stackchange); RecordTokenFixup(); PutInteger4(tk); }
internal void Emit(OpCode opcode, LocalBuilder local) { _ilg.Emit(opcode, local); int tempVal = local.LocalIndex; if (opcode.Equals(OpCodes.Ldloc)) { switch (tempVal) { case 0: opcode = OpCodes.Ldloc_0; break; case 1: opcode = OpCodes.Ldloc_1; break; case 2: opcode = OpCodes.Ldloc_2; break; case 3: opcode = OpCodes.Ldloc_3; break; default: if (tempVal <= 255) opcode = OpCodes.Ldloc_S; break; } } else if (opcode.Equals(OpCodes.Stloc)) { switch (tempVal) { case 0: opcode = OpCodes.Stloc_0; break; case 1: opcode = OpCodes.Stloc_1; break; case 2: opcode = OpCodes.Stloc_2; break; case 3: opcode = OpCodes.Stloc_3; break; default: if (tempVal <= 255) opcode = OpCodes.Stloc_S; break; } } else if (opcode.Equals(OpCodes.Ldloca)) { if (tempVal <= 255) opcode = OpCodes.Ldloca_S; } AdvanceOffset(opcode); if (opcode.OperandType == OperandType.InlineNone) return; else if (!OpCodes.TakesSingleByteArgument(opcode)) { _offset += 2; } else { _offset++; } AssertOffsetMatches(); }
public override void Emit(OpCode opcode, SignatureHelper signature) { if (signature == null) throw new ArgumentNullException(nameof(signature)); Contract.EndContractBlock(); int stackchange = 0; EnsureCapacity(7); InternalEmit(opcode); // The only IL instruction that has VarPop behaviour, that takes a // Signature token as a parameter is calli. Pop the parameters and // the native function pointer. To be conservative, do not pop the // this pointer since this information is not easily derived from // SignatureHelper. if (opcode.StackBehaviourPop == StackBehaviour.Varpop) { Contract.Assert(opcode.Equals(OpCodes.Calli), "Unexpected opcode encountered for StackBehaviour VarPop."); // Pop the arguments.. stackchange -= signature.ArgumentCount; // Pop native function pointer off the stack. stackchange--; UpdateStackSize(opcode, stackchange); } int token = GetTokenForSig(signature.GetSignature(true)); ; PutInteger4(token); }
public virtual void Emit(OpCode opcode, LocalBuilder local) { if (local == null) { throw new ArgumentNullException("local"); } int localIndex = local.GetLocalIndex(); if (local.GetMethodBuilder() != this.m_methodBuilder) { throw new ArgumentException(Environment.GetResourceString("Argument_UnmatchedMethodForLocal"), "local"); } if (opcode.Equals(OpCodes.Ldloc)) { switch (localIndex) { case 0: opcode = OpCodes.Ldloc_0; goto Label_0123; case 1: opcode = OpCodes.Ldloc_1; goto Label_0123; case 2: opcode = OpCodes.Ldloc_2; goto Label_0123; case 3: opcode = OpCodes.Ldloc_3; goto Label_0123; } if (localIndex <= 0xff) { opcode = OpCodes.Ldloc_S; } } else if (opcode.Equals(OpCodes.Stloc)) { switch (localIndex) { case 0: opcode = OpCodes.Stloc_0; goto Label_0123; case 1: opcode = OpCodes.Stloc_1; goto Label_0123; case 2: opcode = OpCodes.Stloc_2; goto Label_0123; case 3: opcode = OpCodes.Stloc_3; goto Label_0123; } if (localIndex <= 0xff) { opcode = OpCodes.Stloc_S; } } else if (opcode.Equals(OpCodes.Ldloca) && (localIndex <= 0xff)) { opcode = OpCodes.Ldloca_S; } Label_0123: this.EnsureCapacity(7); this.InternalEmit(opcode); if (opcode.OperandType != OperandType.InlineNone) { if (!OpCodes.TakesSingleByteArgument(opcode)) { this.m_ILStream[this.m_length++] = (byte) localIndex; this.m_ILStream[this.m_length++] = (byte) (localIndex >> 8); } else { if (localIndex > 0xff) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadInstructionOrIndexOutOfBound")); } this.m_ILStream[this.m_length++] = (byte) localIndex; } } }
// Puts opcode onto the stream and then the metadata token represented // by meth. The location of <VAR>meth</VAR> is recorded so that the token can be // patched if necessary when persisting the module to a PE. /// <include file='doc\ILGenerator.uex' path='docs/doc[@for="ILGenerator.Emit5"]/*' /> public virtual void Emit(OpCode opcode, MethodInfo meth) { int stackchange = 0; if (meth == null) throw new ArgumentNullException("meth"); ModuleBuilder modBuilder = (ModuleBuilder) m_methodBuilder.GetModule(); int tempVal = modBuilder.GetMethodToken( meth ).Token; EnsureCapacity(7); internalEmit(opcode); // The only IL instructions that have a Varpush stack behaviour // that take a Method token as an operand are, call and callvirt. // Push one if there is a non-void return value. if (opcode.m_push == StackBehaviour.Varpush) { BCLDebug.Assert(opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt), "Unexpected opcode encountered for StackBehaviour of VarPush."); if (meth.ReturnType != typeof(void)) stackchange++; } // The only IL instructions that have a Varpop stack behaviour and that // take a MethodToken as an operand are call, callvirt and newobj. Pop the // parameters including "this" if there is one. Do not pop the this // parameter for newobj instruction. if (opcode.m_pop == StackBehaviour.Varpop) { BCLDebug.Assert(opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt) || opcode.Equals(OpCodes.Newobj), "Unexpected opcode encountered for StackBehaviour of VarPush."); if (meth is MethodBuilder) { if (((MethodBuilder)meth).GetParameterTypes() != null) stackchange -= ((MethodBuilder)meth).GetParameterTypes().Length; } else if (meth is SymbolMethod) { if (((SymbolMethod)meth).GetParameterTypes() != null) stackchange -= ((SymbolMethod)meth).GetParameterTypes().Length; } else if (meth.GetParameters() != null) stackchange -= meth.GetParameters().Length; if (!(meth is SymbolMethod) && meth.IsStatic == false && !(opcode.Equals(OpCodes.Newobj))) stackchange--; } UpdateStackSize(opcode, stackchange); RecordTokenFixup(); m_length=PutInteger4(tempVal, m_length, m_ILStream); }
public virtual void Emit(OpCode opcode, LocalBuilder local) { if (local == null) { throw new ArgumentNullException("local"); } int localIndex = local.GetLocalIndex(); if (local.GetMethodBuilder() != this.m_methodBuilder) { throw new ArgumentException(Environment.GetResourceString("Argument_UnmatchedMethodForLocal"), "local"); } if (opcode.Equals(OpCodes.Ldloc)) { switch (localIndex) { case 0: opcode = OpCodes.Ldloc_0; goto Label_0123; case 1: opcode = OpCodes.Ldloc_1; goto Label_0123; case 2: opcode = OpCodes.Ldloc_2; goto Label_0123; case 3: opcode = OpCodes.Ldloc_3; goto Label_0123; } if (localIndex <= 0xff) { opcode = OpCodes.Ldloc_S; } } else if (opcode.Equals(OpCodes.Stloc)) { switch (localIndex) { case 0: opcode = OpCodes.Stloc_0; goto Label_0123; case 1: opcode = OpCodes.Stloc_1; goto Label_0123; case 2: opcode = OpCodes.Stloc_2; goto Label_0123; case 3: opcode = OpCodes.Stloc_3; goto Label_0123; } if (localIndex <= 0xff) { opcode = OpCodes.Stloc_S; } } else if (opcode.Equals(OpCodes.Ldloca) && (localIndex <= 0xff)) { opcode = OpCodes.Ldloca_S; } Label_0123: this.EnsureCapacity(7); this.InternalEmit(opcode); if (opcode.OperandType != OperandType.InlineNone) { if (!OpCodes.TakesSingleByteArgument(opcode)) { this.m_ILStream[this.m_length++] = (byte)localIndex; this.m_ILStream[this.m_length++] = (byte)(localIndex >> 8); } else { if (localIndex > 0xff) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadInstructionOrIndexOutOfBound")); } this.m_ILStream[this.m_length++] = (byte)localIndex; } } }
public virtual void Emit(OpCode opcode, ConstructorInfo con) { int stackchange = 0; int tk = GetMethodToken(con, null); EnsureCapacity(7); InternalEmit(opcode); // Make a conservative estimate by assuming a return type and no // this parameter. if (opcode.m_push == StackBehaviour.Varpush) { // Instruction must be one of call or callvirt. BCLDebug.Assert(opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt), "Unexpected opcode encountered for StackBehaviour of VarPush."); stackchange++; } if (opcode.m_pop == StackBehaviour.Varpop) { // Instruction must be one of call, callvirt or newobj. BCLDebug.Assert(opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt) || opcode.Equals(OpCodes.Newobj), "Unexpected opcode encountered for StackBehaviour of VarPop."); if (con.GetParameterTypes() != null) stackchange -= con.GetParameterTypes().Length; } UpdateStackSize(opcode, stackchange); RecordTokenFixup(); m_length=PutInteger4(tk, m_length, m_ILStream); }
public override void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[] optionalParameterTypes) { int tk; int stackchange = 0; if (methodInfo == null) throw new ArgumentNullException("methodInfo"); if (methodInfo.ContainsGenericParameters) throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "methodInfo"); if (methodInfo.DeclaringType != null && methodInfo.DeclaringType.ContainsGenericParameters) throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "methodInfo"); tk = GetMemberRefToken(methodInfo, optionalParameterTypes); EnsureCapacity(7); InternalEmit(opcode); // The opcode must be one of call, callvirt, or newobj. BCLDebug.Assert(opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt) || opcode.Equals(OpCodes.Newobj), "Unexpected opcode passed to EmitCall."); // Push the return value if there is one. if (methodInfo.ReturnType != typeof(void)) stackchange++; // Pop the parameters. stackchange -= methodInfo.GetParameterTypes().Length; // Pop the this parameter if the method is non-static and the // instruction is not newobj. if (!(methodInfo is SymbolMethod) && methodInfo.IsStatic == false && !(opcode.Equals(OpCodes.Newobj))) stackchange--; // Pop the optional parameters off the stack. if (optionalParameterTypes != null) stackchange -= optionalParameterTypes.Length; UpdateStackSize(opcode, stackchange); m_length = PutInteger4(tk, m_length, m_ILStream); }
internal static void EmitDecimalToIntegerTruncatedConversion(ILGenerator il, OpCode opConversion) { il.Emit(OpCodes.Call, CompilerGlobals.uncheckedDecimalToInt64Method); if (!opConversion.Equals(OpCodes.Conv_I8)) il.Emit(opConversion); }
//*********************************************** // // Emit calli instructions // //*********************************************** /// <include file='doc\ILGenerator.uex' path='docs/doc[@for="ILGenerator.EmitCalli"]/*' /> public void EmitCalli( OpCode opcode, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Type[] optionalParameterTypes) { int stackchange = 0; SignatureHelper sig; if (optionalParameterTypes != null) { if ((callingConvention & CallingConventions.VarArgs) == 0) { // This is bad! Client should not supply optional parameter in default calling convention throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAVarArgCallingConvention")); } } ModuleBuilder modBuilder = (ModuleBuilder) m_methodBuilder.GetModule(); sig = GetVarArgSignature(callingConvention, returnType, parameterTypes, optionalParameterTypes); EnsureCapacity(7); Emit(OpCodes.Calli); // The opcode passed in must be the calli instruction. BCLDebug.Assert(opcode.Equals(OpCodes.Calli), "Unexpected opcode passed to EmitCalli."); // If there is a non-void return type, push one. if (returnType != typeof(void)) stackchange++; // Pop off arguments if any. if (parameterTypes != null) stackchange -= parameterTypes.Length; // Pop off vararg arguments. if (optionalParameterTypes != null) stackchange -= optionalParameterTypes.Length; // Pop the this parameter if the method has a this parameter. if ((callingConvention & CallingConventions.HasThis) == CallingConventions.HasThis) stackchange--; // Pop the native function pointer. stackchange--; UpdateStackSize(opcode, stackchange); RecordTokenFixup(); m_length=PutInteger4(modBuilder.GetSignatureToken(sig).Token, m_length, m_ILStream); }
// // // Token resolution calls // // public override void Emit(OpCode opcode, MethodInfo meth) { if (meth == null) { throw new ArgumentNullException("meth"); } int stackchange = 0; int tempVal = 0; DynamicMethod dynMeth = DynamicMethod.AsDynamicMethod(meth); if (dynMeth == null) { if (!(meth is RuntimeMethodInfo)) { throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "meth"); } if (meth.DeclaringType != null && (meth.DeclaringType.IsGenericType || meth.DeclaringType.IsArray)) { tempVal = m_scope.GetTokenFor(meth.MethodHandle, meth.DeclaringType.TypeHandle); } else { tempVal = m_scope.GetTokenFor(meth.MethodHandle); } } else { // rule out not allowed operations on DynamicMethods if (opcode.Equals(OpCodes.Ldtoken) || opcode.Equals(OpCodes.Ldftn) || opcode.Equals(OpCodes.Ldvirtftn)) { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOpCodeOnDynamicMethod")); } tempVal = m_scope.GetTokenFor(dynMeth); } EnsureCapacity(7); InternalEmit(opcode); if (opcode.m_push == StackBehaviour.Varpush && meth.ReturnType != typeof(void)) { stackchange++; } if (opcode.m_pop == StackBehaviour.Varpop) { stackchange -= meth.GetParametersNoCopy().Length; } // Pop the "this" parameter if the method is non-static, // and the instruction is not newobj/ldtoken/ldftn. if (!meth.IsStatic && !(opcode.Equals(OpCodes.Newobj) || opcode.Equals(OpCodes.Ldtoken) || opcode.Equals(OpCodes.Ldftn))) { stackchange--; } UpdateStackSize(opcode, stackchange); m_length = PutInteger4(tempVal, m_length, m_ILStream); }
//*********************************************** // // Emit calli instructions taking a unmanaged calling convention // System.Runtime.InteropServices such as STDCALL, CDECL,.. // //*********************************************** /// <include file='doc\ILGenerator.uex' path='docs/doc[@for="ILGenerator.EmitCalli1"]/*' /> public void EmitCalli( OpCode opcode, CallingConvention unmanagedCallConv, Type returnType, Type[] parameterTypes) { int stackchange = 0; int cParams = 0; int i; SignatureHelper sig; ModuleBuilder modBuilder = (ModuleBuilder) m_methodBuilder.GetModule(); // The opcode passed in must be the calli instruction. BCLDebug.Assert(opcode.Equals(OpCodes.Calli), "Unexpected opcode passed to EmitCalli."); if (parameterTypes != null) { cParams = parameterTypes.Length; } sig = SignatureHelper.GetMethodSigHelper( m_methodBuilder.GetModule(), unmanagedCallConv, returnType); if (parameterTypes != null) { for (i = 0; i < cParams; i++) { sig.AddArgument(parameterTypes[i]); } } // If there is a non-void return type, push one. if (returnType != typeof(void)) stackchange++; // Pop off arguments if any. if (parameterTypes != null) stackchange -= cParams; // Pop the native function pointer. stackchange--; UpdateStackSize(opcode, stackchange); EnsureCapacity(7); Emit(OpCodes.Calli); RecordTokenFixup(); m_length=PutInteger4(modBuilder.GetSignatureToken(sig).Token, m_length, m_ILStream); }
internal static void EmitDoubleToIntegerTruncatedConversion(ILGenerator il, OpCode opConversion) { il.Emit(OpCodes.Call, CompilerGlobals.doubleToInt64); if (!opConversion.Equals(OpCodes.Conv_I8)) il.Emit(opConversion); }
//*********************************************** // // Emit call instructions // //*********************************************** /// <include file='doc\ILGenerator.uex' path='docs/doc[@for="ILGenerator.EmitCall"]/*' /> public void EmitCall( OpCode opcode, // call instruction, such as call, callvirt, calli MethodInfo methodInfo, // target method Type[] optionalParameterTypes) // optional parameters if methodInfo is a vararg method { int tk; int stackchange = 0; if (methodInfo == null) throw new ArgumentNullException("methodInfo"); ModuleBuilder modBuilder = (ModuleBuilder) m_methodBuilder.GetModule(); tk = GetVarArgMemberRefToken(methodInfo, optionalParameterTypes); EnsureCapacity(7); internalEmit(opcode); // The opcode must be one of call, callvirt, or newobj. BCLDebug.Assert(opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt) || opcode.Equals(OpCodes.Newobj), "Unexpected opcode passed to EmitCall."); // Push the return value if there is one. if (methodInfo.ReturnType != typeof(void)) stackchange++; // Pop the parameters. if (methodInfo is MethodBuilder) { if (((MethodBuilder)methodInfo).GetParameterTypes() != null) stackchange -= ((MethodBuilder)methodInfo).GetParameterTypes().Length; } else if (methodInfo is SymbolMethod) { if (((SymbolMethod)methodInfo).GetParameterTypes() != null) stackchange -= ((SymbolMethod)methodInfo).GetParameterTypes().Length; } else if (methodInfo.GetParameters() != null) stackchange -= methodInfo.GetParameters().Length; // Pop the this parameter if the method is non-static and the // instruction is not newobj. if (!(methodInfo is SymbolMethod) && methodInfo.IsStatic == false && !(opcode.Equals(OpCodes.Newobj))) stackchange--; // Pop the optional parameters off the stack. if (optionalParameterTypes != null) stackchange -= optionalParameterTypes.Length; UpdateStackSize(opcode, stackchange); RecordTokenFixup(); m_length=PutInteger4(tk, m_length, m_ILStream); }
[System.Security.SecuritySafeCritical] // auto-generated public override void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[] optionalParameterTypes) { if (methodInfo == null) throw new ArgumentNullException(nameof(methodInfo)); if (!(opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt) || opcode.Equals(OpCodes.Newobj))) throw new ArgumentException(Environment.GetResourceString("Argument_NotMethodCallOpcode"), nameof(opcode)); if (methodInfo.ContainsGenericParameters) throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), nameof(methodInfo)); if (methodInfo.DeclaringType != null && methodInfo.DeclaringType.ContainsGenericParameters) throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), nameof(methodInfo)); Contract.EndContractBlock(); int tk; int stackchange = 0; tk = GetMemberRefToken(methodInfo, optionalParameterTypes); EnsureCapacity(7); InternalEmit(opcode); // Push the return value if there is one. if (methodInfo.ReturnType != typeof(void)) stackchange++; // Pop the parameters. stackchange -= methodInfo.GetParameterTypes().Length; // Pop the this parameter if the method is non-static and the // instruction is not newobj. if (!(methodInfo is SymbolMethod) && methodInfo.IsStatic == false && !(opcode.Equals(OpCodes.Newobj))) stackchange--; // Pop the optional parameters off the stack. if (optionalParameterTypes != null) stackchange -= optionalParameterTypes.Length; UpdateStackSize(opcode, stackchange); PutInteger4(tk); }
/// <include file='doc\ILGenerator.uex' path='docs/doc[@for="ILGenerator.Emit7"]/*' /> public virtual void Emit(OpCode opcode, ConstructorInfo con) { int stackchange = 0; ModuleBuilder modBuilder = (ModuleBuilder) m_methodBuilder.GetModule(); int tempVal = modBuilder.GetConstructorToken( con ).Token; EnsureCapacity(7); internalEmit(opcode); // Make a conservative estimate by assuming a return type and no // this parameter. if (opcode.m_push == StackBehaviour.Varpush) { // Instruction must be one of call or callvirt. BCLDebug.Assert(opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt), "Unexpected opcode encountered for StackBehaviour of VarPush."); stackchange++; } if (opcode.m_pop == StackBehaviour.Varpop) { // Instruction must be one of call, callvirt or newobj. BCLDebug.Assert(opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt) || opcode.Equals(OpCodes.Newobj), "Unexpected opcode encountered for StackBehaviour of VarPop."); if (con is RuntimeConstructorInfo) { if (con.GetParameters() != null) stackchange -= con.GetParameters().Length; } else if (con is ConstructorBuilder) { if (((ConstructorBuilder)con).m_methodBuilder.GetParameterTypes() != null) stackchange -= ((ConstructorBuilder)con).m_methodBuilder.GetParameterTypes().Length; } else BCLDebug.Assert(false, "Unexpected type of ConstructorInfo encountered."); } UpdateStackSize(opcode, stackchange); RecordTokenFixup(); m_length=PutInteger4(tempVal, m_length, m_ILStream); }
[System.Security.SecuritySafeCritical] // auto-generated public override void Emit(OpCode opcode, MethodInfo meth) { if (meth == null) throw new ArgumentNullException(nameof(meth)); Contract.EndContractBlock(); int stackchange = 0; int token = 0; DynamicMethod dynMeth = meth as DynamicMethod; if (dynMeth == null) { RuntimeMethodInfo rtMeth = meth as RuntimeMethodInfo; if (rtMeth == null) throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), nameof(meth)); RuntimeType declaringType = rtMeth.GetRuntimeType(); if (declaringType != null && (declaringType.IsGenericType || declaringType.IsArray)) token = GetTokenFor(rtMeth, declaringType); else token = GetTokenFor(rtMeth); } else { // rule out not allowed operations on DynamicMethods if (opcode.Equals(OpCodes.Ldtoken) || opcode.Equals(OpCodes.Ldftn) || opcode.Equals(OpCodes.Ldvirtftn)) { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOpCodeOnDynamicMethod")); } token = GetTokenFor(dynMeth); } EnsureCapacity(7); InternalEmit(opcode); if (opcode.StackBehaviourPush == StackBehaviour.Varpush && meth.ReturnType != typeof(void)) { stackchange++; } if (opcode.StackBehaviourPop == StackBehaviour.Varpop) { stackchange -= meth.GetParametersNoCopy().Length; } // Pop the "this" parameter if the method is non-static, // and the instruction is not newobj/ldtoken/ldftn. if (!meth.IsStatic && !(opcode.Equals(OpCodes.Newobj) || opcode.Equals(OpCodes.Ldtoken) || opcode.Equals(OpCodes.Ldftn))) { stackchange--; } UpdateStackSize(opcode, stackchange); PutInteger4(token); }
public void Emit(OpCode opcode, Label lblVal) { Debug.Assert(!opcode.Equals(OpCodes.Br) && !opcode.Equals(OpCodes.Br_S), "Use EmitUnconditionalBranch and be careful not to emit unverifiable code."); #if DEBUG if (XmlILTrace.IsEnabled) this.writerDump.WriteLine(" {0, -10} Label {1}", opcode.Name, this.symbols[lblVal]); #endif _ilgen.Emit(opcode, lblVal); }
/// <summary> /// Unconditional branch opcodes (OpCode.Br, OpCode.Br_S) can lead to unverifiable code in the following cases: /// /// # DEAD CODE CASE /// ldc_i4 1 # Stack depth == 1 /// br Label2 /// Label1: /// nop # Dead code, so IL rules assume stack depth == 0. This causes a verification error, /// # since next instruction has depth == 1 /// Label2: /// pop # Stack depth == 1 /// ret /// /// # LATE BRANCH CASE /// ldc_i4 1 # Stack depth == 1 /// br Label2 /// Label1: /// nop # Not dead code, but since branch comes from below, IL rules assume stack depth = 0. /// # This causes a verification error, since next instruction has depth == 1 /// Label2: /// pop # Stack depth == 1 /// ret /// Label3: /// br Label1 # Stack depth == 1 /// /// This method works around the above limitations by using Brtrue or Brfalse in the following way: /// /// ldc_i4 1 # Since this test is always true, this is a way of creating a path to the code that /// brtrue Label # follows the brtrue instruction. /// /// ldc_i4 1 # Since this test is always false, this is a way of creating a path to the code that /// brfalse Label # starts at Label. /// /// 1. If opcode == Brtrue or Brtrue_S, then 1 will be pushed and brtrue instruction will be generated. /// 2. If opcode == Brfalse or Brfalse_S, then 1 will be pushed and brfalse instruction will be generated. /// 3. If opcode == Br or Br_S, then a br instruction will be generated. /// </summary> public void EmitUnconditionalBranch(OpCode opcode, Label lblTarget) { if (!opcode.Equals(OpCodes.Br) && !opcode.Equals(OpCodes.Br_S)) { Debug.Assert(opcode.Equals(OpCodes.Brtrue) || opcode.Equals(OpCodes.Brtrue_S) || opcode.Equals(OpCodes.Brfalse) || opcode.Equals(OpCodes.Brfalse_S)); Emit(OpCodes.Ldc_I4_1); } #if DEBUG if (XmlILTrace.IsEnabled) this.writerDump.WriteLine(" {0, -10} Label {1}", opcode.Name, this.symbols[lblTarget]); #endif _ilgen.Emit(opcode, lblTarget); if (_lastSourceInfo != null && (opcode.Equals(OpCodes.Br) || opcode.Equals(OpCodes.Br_S))) { // Emit a "no source" sequence point, otherwise the following label will be preceded // with a dead Nop operation, which may lead to unverifiable code (SQLBUDT 423393). // We are guaranteed not to emit adjacent sequence points because Br or Br_S // instruction precedes this sequence point, and a Nop instruction precedes other // sequence points. MarkSequencePoint(SourceLineInfo.NoSource); } }
public static OpCodeGroup GetGroupOfOpCode(OpCode opCode) { OpCodeGroup result = OpCodeGroup.Parameterless; if (FieldParameter.Contains(opCode)) { result = OpCodeGroup.FieldParameter; } else if (MethodParameter.Contains(opCode)) { result = OpCodeGroup.MethodParameter; } else if (StringParameter.Contains(opCode)) { result = OpCodeGroup.StringParameter; } else if (TypeParameter.Contains(opCode)) { result = OpCodeGroup.TypeParameter; } else if (SbyteLocationParameter.Contains(opCode)) { result = OpCodeGroup.SbyteLocationParameter; } else if (IntLocationParameter.Contains(opCode)) { result = OpCodeGroup.IntLocationParameter; } else if (ByteParameter.Contains(opCode)) { result = OpCodeGroup.ByteParameter; } else if (UshortParameter.Contains(opCode)) { result = OpCodeGroup.UshortParameter; } else if (SbyteParameter.Contains(opCode)) { result = OpCodeGroup.SbyteParameter; } else if (IntParameter.Contains(opCode)) { result = OpCodeGroup.IntParameter; } else if (LongParameter.Contains(opCode)) { result = OpCodeGroup.LongParameter; } else if (FloatParameter.Contains(opCode)) { result = OpCodeGroup.FloatParameter; } else if (DoubleParameter.Contains(opCode)) { result = OpCodeGroup.DoubleParameter; } else if (ByteArgumentParameter.Contains(opCode)) { result = OpCodeGroup.ByteArgumentParameter; } else if (UshortArgumentParameter.Contains(opCode)) { result = OpCodeGroup.UshortArgumentParameter; } else if (ByteVariableParameter.Contains(opCode)) { result = OpCodeGroup.ByteVariableParameter; } else if (UshortVariableParameter.Contains(opCode)) { result = OpCodeGroup.UshortVariableParameter; } else if (opCode.Equals(OpCodes.Calli)) { result = OpCodeGroup.Calli; } else if (opCode.Equals(OpCodes.Switch)) { result = OpCodeGroup.Switch; } else if (opCode.Equals(OpCodes.Ldtoken)) { result = OpCodeGroup.Ldtoken; } return result; }
public void Emit(OpCode opcode, MethodInfo methInfo) { Debug.Assert(!opcode.Equals(OpCodes.Call) && !opcode.Equals(OpCodes.Callvirt), "Use Call so that debug information will be output correctly."); #if DEBUG if (XmlILTrace.IsEnabled) this.writerDump.WriteLine(" {0, -10} {1}", opcode.Name, methInfo.Name); #endif _ilgen.Emit(opcode, methInfo); }
/// <summary> /// Unconditional branch opcodes (OpCode.Br, OpCode.Br_S) can lead to unverifiable code in the following cases: /// /// # DEAD CODE CASE /// ldc_i4 1 # Stack depth == 1 /// br Label2 /// Label1: /// nop # Dead code, so IL rules assume stack depth == 0. This causes a verification error, /// # since next instruction has depth == 1 /// Label2: /// pop # Stack depth == 1 /// ret /// /// # LATE BRANCH CASE /// ldc_i4 1 # Stack depth == 1 /// br Label2 /// Label1: /// nop # Not dead code, but since branch comes from below, IL rules assume stack depth = 0. /// # This causes a verification error, since next instruction has depth == 1 /// Label2: /// pop # Stack depth == 1 /// ret /// Label3: /// br Label1 # Stack depth == 1 /// /// This method works around the above limitations by using Brtrue or Brfalse in the following way: /// /// ldc_i4 1 # Since this test is always true, this is a way of creating a path to the code that /// brtrue Label # follows the brtrue instruction. /// /// ldc_i4 1 # Since this test is always false, this is a way of creating a path to the code that /// brfalse Label # starts at Label. /// /// 1. If opcode == Brtrue or Brtrue_S, then 1 will be pushed and brtrue instruction will be generated. /// 2. If opcode == Brfalse or Brfalse_S, then 1 will be pushed and brfalse instruction will be generated. /// 3. If opcode == Br or Br_S, then a br instruction will be generated. /// </summary> public void EmitUnconditionalBranch(OpCode opcode, Label lblTarget) { if (!opcode.Equals(OpCodes.Br) && !opcode.Equals(OpCodes.Br_S)) { Debug.Assert(opcode.Equals(OpCodes.Brtrue) || opcode.Equals(OpCodes.Brtrue_S) || opcode.Equals(OpCodes.Brfalse) || opcode.Equals(OpCodes.Brfalse_S)); Emit(OpCodes.Ldc_I4_1); } #if DEBUG if (XmlILTrace.IsEnabled) this.writerDump.WriteLine(" {0, -10} Label {1}", opcode.Name, this.symbols[lblTarget]); #endif this.ilgen.Emit(opcode, lblTarget); }
[System.Security.SecuritySafeCritical] // auto-generated public virtual void Emit(OpCode opcode, MethodInfo meth) { if (meth == null) throw new ArgumentNullException("meth"); Contract.EndContractBlock(); if (opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt) || opcode.Equals(OpCodes.Newobj)) { EmitCall(opcode, meth, null); } else { int stackchange = 0; // Reflection doesn't distinguish between these two concepts: // 1. A generic method definition: Foo`1 // 2. A generic method definition instantiated over its own generic arguments: Foo`1<!!0> // In RefEmit, we always want 1 for Ld* opcodes and 2 for Call* and Newobj. bool useMethodDef = opcode.Equals(OpCodes.Ldtoken) || opcode.Equals(OpCodes.Ldftn) || opcode.Equals(OpCodes.Ldvirtftn); int tk = GetMethodToken(meth, null, useMethodDef); EnsureCapacity(7); InternalEmit(opcode); UpdateStackSize(opcode, stackchange); RecordTokenFixup(); PutInteger4(tk); } }
// // // Signature related calls (vararg, calli) // // public override void EmitCalli(OpCode opcode, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Type[] optionalParameterTypes) { int stackchange = 0; SignatureHelper sig; if (optionalParameterTypes != null) if ((callingConvention & CallingConventions.VarArgs) == 0) throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAVarArgCallingConvention")); sig = GetMemberRefSignature(callingConvention, returnType, parameterTypes, optionalParameterTypes); EnsureCapacity(7); Emit(OpCodes.Calli); // The opcode passed in must be the calli instruction. BCLDebug.Assert(opcode.Equals(OpCodes.Calli), "Unexpected opcode passed to EmitCalli."); // If there is a non-void return type, push one. if (returnType != typeof(void)) stackchange++; // Pop off arguments if any. if (parameterTypes != null) stackchange -= parameterTypes.Length; // Pop off vararg arguments. if (optionalParameterTypes != null) stackchange -= optionalParameterTypes.Length; // Pop the this parameter if the method has a this parameter. if ((callingConvention & CallingConventions.HasThis) == CallingConventions.HasThis) stackchange--; // Pop the native function pointer. stackchange--; UpdateStackSize(opcode, stackchange); int token = AddSignature(sig.GetSignature(true)); m_length=PutInteger4(token, m_length, m_ILStream); }
public virtual void Emit(OpCode opcode, SignatureHelper signature) { if (signature == null) throw new ArgumentNullException("signature"); Contract.EndContractBlock(); int stackchange = 0; ModuleBuilder modBuilder = (ModuleBuilder)m_methodBuilder.Module; SignatureToken sig = modBuilder.GetSignatureToken(signature); int tempVal = sig.Token; EnsureCapacity(7); InternalEmit(opcode); // The only IL instruction that has VarPop behaviour, that takes a // Signature token as a parameter is calli. Pop the parameters and // the native function pointer. To be conservative, do not pop the // this pointer since this information is not easily derived from // SignatureHelper. if (opcode.StackBehaviourPop == StackBehaviour.Varpop) { Contract.Assert(opcode.Equals(OpCodes.Calli), "Unexpected opcode encountered for StackBehaviour VarPop."); // Pop the arguments.. stackchange -= signature.ArgumentCount; // Pop native function pointer off the stack. stackchange--; UpdateStackSize(opcode, stackchange); } RecordTokenFixup(); PutInteger4(tempVal); }
public override void EmitCalli(OpCode opcode, CallingConvention unmanagedCallConv, Type returnType, Type[] parameterTypes) { int stackchange = 0; int cParams = 0; int i; SignatureHelper sig; // The opcode passed in must be the calli instruction. BCLDebug.Assert(opcode.Equals(OpCodes.Calli), "Unexpected opcode passed to EmitCalli."); if (parameterTypes != null) cParams = parameterTypes.Length; sig = SignatureHelper.GetMethodSigHelper(unmanagedCallConv, returnType); if (parameterTypes != null) for (i = 0; i < cParams; i++) sig.AddArgument(parameterTypes[i]); // If there is a non-void return type, push one. if (returnType != typeof(void)) stackchange++; // Pop off arguments if any. if (parameterTypes != null) stackchange -= cParams; // Pop the native function pointer. stackchange--; UpdateStackSize(opcode, stackchange); EnsureCapacity(7); Emit(OpCodes.Calli); int token = AddSignature(sig.GetSignature(true)); m_length = PutInteger4(token, m_length, m_ILStream); }
public virtual void Emit(OpCode opcode, LocalBuilder local) { // Puts the opcode onto the IL stream followed by the information for local variable local. if (local == null) { throw new ArgumentNullException("local"); } Contract.EndContractBlock(); int tempVal = local.GetLocalIndex(); if (local.GetMethodBuilder() != m_methodBuilder) { throw new ArgumentException(Environment.GetResourceString("Argument_UnmatchedMethodForLocal"), "local"); } // If the instruction is a ldloc, ldloca a stloc, morph it to the optimal form. if (opcode.Equals(OpCodes.Ldloc)) { switch(tempVal) { case 0: opcode = OpCodes.Ldloc_0; break; case 1: opcode = OpCodes.Ldloc_1; break; case 2: opcode = OpCodes.Ldloc_2; break; case 3: opcode = OpCodes.Ldloc_3; break; default: if (tempVal <= 255) opcode = OpCodes.Ldloc_S; break; } } else if (opcode.Equals(OpCodes.Stloc)) { switch(tempVal) { case 0: opcode = OpCodes.Stloc_0; break; case 1: opcode = OpCodes.Stloc_1; break; case 2: opcode = OpCodes.Stloc_2; break; case 3: opcode = OpCodes.Stloc_3; break; default: if (tempVal <= 255) opcode = OpCodes.Stloc_S; break; } } else if (opcode.Equals(OpCodes.Ldloca)) { if (tempVal <= 255) opcode = OpCodes.Ldloca_S; } EnsureCapacity(7); InternalEmit(opcode); if (opcode.OperandType == OperandType.InlineNone) return; else if (!OpCodes.TakesSingleByteArgument(opcode)) { m_ILStream[m_length++]=(byte) tempVal; m_ILStream[m_length++]=(byte) (tempVal>>8); } else { //Handle stloc_1, ldloc_1 if (tempVal > Byte.MaxValue) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadInstructionOrIndexOutOfBound")); } m_ILStream[m_length++]=(byte)tempVal; } }
public virtual void Emit(OpCode opcode, MethodInfo meth) { if (opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt) || opcode.Equals(OpCodes.Newobj)) { EmitCall(opcode, meth, null); } else { int stackchange = 0; if (meth == null) throw new ArgumentNullException("meth"); int tk = GetMethodToken(meth, null); EnsureCapacity(7); InternalEmit(opcode); UpdateStackSize(opcode, stackchange); RecordTokenFixup(); m_length=PutInteger4(tk, m_length, m_ILStream); } }