本文整理汇总了C#中PHP.Core.Emit.ILEmitter.Emit方法的典型用法代码示例。如果您正苦于以下问题:C# ILEmitter.Emit方法的具体用法?C# ILEmitter.Emit怎么用?C# ILEmitter.Emit使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类PHP.Core.Emit.ILEmitter
的用法示例。
在下文中一共展示了ILEmitter.Emit方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: EmitAddFrame
public static void EmitAddFrame(ILEmitter/*!*/ il, IPlace/*!*/ scriptContextPlace, int typeArgCount, int argCount,
Action<ILEmitter, int> typeArgEmitter, Action<ILEmitter, int>/*!*/ argEmitter)
{
Debug.Assert(typeArgCount == 0 || typeArgEmitter != null);
// type args:
if (typeArgCount > 0)
{
scriptContextPlace.EmitLoad(il);
il.Emit(OpCodes.Ldfld, Fields.ScriptContext_Stack);
il.EmitOverloadedArgs(Types.DTypeDesc[0], typeArgCount, Methods.PhpStack.AddTypeFrame.ExplicitOverloads, typeArgEmitter);
}
// args:
scriptContextPlace.EmitLoad(il);
il.Emit(OpCodes.Ldfld, Fields.ScriptContext_Stack);
il.EmitOverloadedArgs(Types.Object[0], argCount, Methods.PhpStack.AddFrame.ExplicitOverloads, argEmitter);
il.Emit(OpCodes.Call, Methods.PhpStack.AddFrame.Overload(argCount));
// AddFrame adds empty type frame by default, so if there are no type parameters, we can skip AddTypeFrame call:
if (typeArgCount > 0)
il.Emit(OpCodes.Call, Methods.PhpStack.AddTypeFrame.Overload(typeArgCount));
}
示例2: EmitArgFullPostCall
public static void EmitArgFullPostCall(ILEmitter/*!*/ il, IPlace/*!*/ stack, LocalBuilder locArgsCount)
{
// args-aware:
if (locArgsCount != null)
{
// CALL stack.RemoveArgsAwareFrame(count);
stack.EmitLoad(il);
il.Ldloc(locArgsCount);
il.Emit(OpCodes.Call, Methods.PhpStack.RemoveArgsAwareFrame);
}
}
示例3: EmitArgFullPreCall
public static void EmitArgFullPreCall(ILEmitter/*!*/ il, IPlace/*!*/ stack, bool argsAware,
int formalParamCount, int formalTypeParamCount, out LocalBuilder locArgsCount)
{
if (argsAware)
{
locArgsCount = il.DeclareLocal(typeof(int));
// locArgsCount = stack.MakeArgsAware(<formal tpye param count | formal param count>);
stack.EmitLoad(il);
il.LdcI4((formalTypeParamCount << 16) | formalParamCount);
il.Emit(OpCodes.Call, Methods.PhpStack.MakeArgsAware);
il.Stloc(locArgsCount);
}
else
{
locArgsCount = null;
// CALL stack.RemoveFrame();
stack.EmitLoad(il);
il.Emit(OpCodes.Call, Methods.PhpStack.RemoveFrame);
}
}
示例4: DefineContextType
public void DefineContextType()
{
linqContextBuilder = cg.IL.TypeBuilder.DefineNestedType(ContextTypeName + cg.IL.GetNextUniqueIndex(),
TypeAttributes.Class | TypeAttributes.NestedPrivate | TypeAttributes.Sealed,
typeof(PHP.Core.LinqContext), null);
// .ctor:
ConstructorBuilder ctor = linqContextBuilder.DefineConstructor(MethodAttributes.Assembly,
CallingConventions.HasThis, Types.LinqContextArgs);
ILEmitter il = new ILEmitter(ctor);
il.Ldarg(0);
il.Ldarg(1);
il.Ldarg(2);
il.Ldarg(3);
il.Ldarg(4);
il.Emit(OpCodes.Call, Constructors.LinqContext);
il.Emit(OpCodes.Ret);
linqContextCtor = ctor;
}
示例5: EmitHelpers
internal void EmitHelpers()
{
CompilationUnit unit = this.CompilationUnit;
ILEmitter il = new ILEmitter(DeclareHelperBuilder);
IndexedPlace script_context_place = new IndexedPlace(PlaceHolder.Argument, 0);
foreach (PhpFunction function in unit.GetDeclaredFunctions())
{
if (function.IsDefinite)
{
CodeGenerator.EmitDeclareFunction(il, script_context_place, function);
}
}
foreach (PhpType type in unit.GetDeclaredTypes())
{
if (type.IsDefinite)
{
// CALL <context>.DeclareType(<type desc>, <name>);
type.EmitAutoDeclareOnScriptContext(il, script_context_place);
}
else if (!type.IsComplete)
{
if (type.IncompleteClassDeclareMethodInfo != null)
{
// check whether base class is known at this point of execution,
// if so, declare this incomplete class immediately. As PHP does.
type.EmitDeclareIncompleteOnScriptContext(il, script_context_place);
}
}
}
foreach (GlobalConstant constant in unit.GetDeclaredConstants())
{
if (constant.IsDefinite)
{
var field = constant.RealField;
Debug.Assert(field != null);
Debug.Assert(field.IsStatic);
// CALL <context>.DeclareConstant(<name>, <value>);
script_context_place.EmitLoad(il);
il.Emit(OpCodes.Ldstr, constant.FullName);
il.LoadLiteralBox(constant.Value); //il.Emit(OpCodes.Ldsfld, field); // const field cannot be referenced in IL
il.Emit(OpCodes.Call, Methods.ScriptContext.DeclareConstant);
}
}
il.Emit(OpCodes.Ret);
}
示例6: EmitLoadInstance
/// <summary>
/// Emit LOAD <paramref name="instance"/>.
/// </summary>ILEmiter
/// <param name="il"><see cref="ILEmitter"/> object instance.</param>
/// <param name="instance">The place where to load the instance from.</param>
/// <param name="declaringType">The type of resulting instance.</param>
/// <remarks>Instance of value types are wrapped in <see cref="ClrValue<T>"/> object instance.</remarks>
internal static void EmitLoadInstance(ILEmitter/*!*/il, IPlace/*!*/instance, Type/*!*/declaringType)
{
Debug.Assert(il != null && instance != null && declaringType != null, "ClrOverloadBuilder.EmitLoadInstance() null argument!");
// LOAD <instance>
instance.EmitLoad(il);
if (declaringType.IsValueType)
{
var clrValueType = ClrObject.valueTypesCache.Get(declaringType).Item1;
Debug.Assert(clrValueType != null, "Specific ClrValue<T> not found!");
// CAST (ClrValue<T>)
il.Emit(OpCodes.Castclass, clrValueType);
// LOAD .realValue
var realValueField = clrValueType.GetField("realValue");
Debug.Assert(realValueField != null, "ClrValue<T>.realValue field not found!");
il.Emit(OpCodes.Ldflda, clrValueType.GetField("realValue"));
}
else
{
// CAST (T)
il.Emit(OpCodes.Castclass, declaringType);
}
}
示例7: EmitConvertToPhp
/// <summary>
/// Converts a value of the given CLR type to PHP value.
/// </summary>
internal static PhpTypeCode EmitConvertToPhp(ILEmitter/*!*/ il, Type/*!*/ type)
{
// box generic parameter
if (type.IsGenericParameter)
{
il.Emit(OpCodes.Box, type);
type = Types.Object[0];
}
switch (Type.GetTypeCode(type))
{
// primitives:
case TypeCode.Boolean: return PhpTypeCode.Boolean;
case TypeCode.Int32: return PhpTypeCode.Integer;
case TypeCode.Int64: return PhpTypeCode.LongInteger;
case TypeCode.Double: return PhpTypeCode.Double;
case TypeCode.String: return PhpTypeCode.String;
// coercion:
case TypeCode.SByte:
case TypeCode.Int16:
case TypeCode.Byte:
case TypeCode.UInt16:
{
il.Emit(OpCodes.Conv_I4);
return PhpTypeCode.Integer;
}
case TypeCode.UInt32: EmitConstrainedCoercion(il, typeof(int), typeof(long), Int32.MaxValue); return PhpTypeCode.Object;
case TypeCode.UInt64: EmitConstrainedCoercion(il, typeof(int), typeof(long), Int32.MaxValue); return PhpTypeCode.Object;
case TypeCode.Single: il.Emit(OpCodes.Conv_R8); return PhpTypeCode.Double;
case TypeCode.Char:
il.Emit(OpCodes.Box, type);
il.Emit(OpCodes.Callvirt, Methods.Object_ToString);
return PhpTypeCode.String;
case TypeCode.DBNull:
{
il.Emit(OpCodes.Pop);
il.Emit(OpCodes.Ldnull);
return PhpTypeCode.Object;
}
case TypeCode.Decimal: // TODO: what to do with this guy?
case TypeCode.DateTime:
{
il.Emit(OpCodes.Box, type);
il.Emit(OpCodes.Call, Methods.ClrObject_Wrap);
return PhpTypeCode.DObject;
}
case TypeCode.Object:
{
if (!typeof(IPhpVariable).IsAssignableFrom(type))
{
if (type.IsValueType)
il.Emit(OpCodes.Box, type);
il.Emit(OpCodes.Call, Methods.ClrObject_WrapDynamic);
return PhpTypeCode.Object;
}
else return PhpTypeCodeEnum.FromType(type);
}
default:
{
Debug.Fail();
return PhpTypeCode.Invalid;
}
}
}
示例8: EmitConvertToClr
/// <summary>
/// Converts a PHP value to the given CLR type (the caller passes a <paramref name="strictnessLocal"/> that will
/// receive one of the <see cref="PHP.Core.ConvertToClr.ConversionStrictness"/> enumeration values that
/// describe the conversion result (the Failed value indicates that conversion was not successful).
/// </summary>
/// <returns><B>True</B> if it the conversion will surely succeed.</returns>
internal static bool EmitConvertToClr(ILEmitter/*!*/ il, PhpTypeCode typeCode,
Type/*!*/ formalType, LocalBuilder/*!*/ strictnessLocal)
{
Debug.Assert(strictnessLocal.LocalType == typeof(ConversionStrictness));
// preprocess the value according to the PHP type code
switch (typeCode)
{
case PhpTypeCode.PhpReference:
{
// dereference
il.Emit(OpCodes.Ldfld, Fields.PhpReference_Value);
typeCode = PhpTypeCode.Object;
break;
}
case PhpTypeCode.ObjectAddress:
{
// dereference
il.Emit(OpCodes.Ldind_Ref);
typeCode = PhpTypeCode.Object;
break;
}
case PhpTypeCode.LinqSource:
case PhpTypeCode.PhpRuntimeChain:
{
Debug.Fail();
return true;
}
}
// special treatment for generic parameters
if (formalType.IsGenericParameter)
{
EmitConvertToClrGeneric(il, formalType, strictnessLocal);
return false;
}
// convert CLR type
return EmitConvertObjectToClr(il, typeCode, formalType, strictnessLocal);
}
示例9: EmitEntryPoint
protected override void EmitEntryPoint(MethodBuilder/*!*/ methodBuilder)
{
ScriptBuilder script_builder = GetEntryScriptBuilder();
Debug.Assert(script_builder.CompilationUnit is ScriptCompilationUnit);
if (script_builder == null)
throw new InvalidOperationException(CoreResources.GetString("entrypoint_not_specified"));
PhpSourceFile entry_file = ((ScriptCompilationUnit)script_builder.CompilationUnit).SourceUnit.SourceFile;
ILEmitter il = new ILEmitter(methodBuilder);
// LOAD new PhpScript.MainHelperDelegate(Default.Main);
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Ldftn, script_builder.MainHelper);
il.Emit(OpCodes.Newobj, Constructors.MainHelperDelegate);
// LOAD <source name>
il.Emit(OpCodes.Ldstr, entry_file.RelativePath.ToString());
// LOAD Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location)
il.Emit(OpCodes.Call, Methods.Assembly.GetEntryAssembly);
il.Emit(OpCodes.Callvirt, Properties.Assembly_Location.GetGetMethod());
il.Emit(OpCodes.Call, Methods.Path.GetDirectoryName);
// ScriptContext.RunApplication(<main helper delegate>, <source name>, <entry assembly directory> );
il.Emit(OpCodes.Call, Methods.ScriptContext.RunApplication);
// RETURN;
il.Emit(OpCodes.Ret);
}
示例10: EmitReturnValueCopy
/// <summary>
/// Emit <see cref="PhpVariable.Copy"/> if needed. It means <see cref="Expression.Access"/> has to be <see cref="AccessType.Read"/> and <paramref name="returnType"/> has to be copiable.
/// </summary>
/// <param name="il">The <see cref="ILEmitter"/>.</param>
/// <param name="returnType"><see cref="PhpTypeCode"/> of function call return value.</param>
protected void EmitReturnValueCopy(ILEmitter/*!*/il, PhpTypeCode returnType)
{
Debug.Assert(il != null);
// copy only if we are reading the return value &&
// only if return type is copiable:
if (access != AccessType.None && // reading, not literals:
PhpTypeCodeEnum.IsDeeplyCopied(returnType) &&
returnType != PhpTypeCode.PhpReference) // PhpSmartReference can be an issue if method returns an object field (but this is handled by binders)
{
il.LdcI4((int)CopyReason.ReturnedByCopy);
il.Emit(OpCodes.Call, Methods.PhpVariable.Copy);
}
}
示例11: EmitSetConversion
internal void EmitSetConversion(ILEmitter/*!*/ il, PhpTypeCode sourceTypeCode, Type/*!*/ targetType)
{
LocalBuilder strictness = il.GetTemporaryLocal(typeof(PHP.Core.ConvertToClr.ConversionStrictness));
if (!ClrOverloadBuilder.EmitConvertToClr(il, sourceTypeCode, targetType, strictness))
{
Label label_ok = il.DefineLabel();
il.Ldloc(strictness);
il.LdcI4((int)PHP.Core.ConvertToClr.ConversionStrictness.Failed);
il.Emit(OpCodes.Ceq);
il.Emit(OpCodes.Brfalse, label_ok);
il.Emit(OpCodes.Ldstr, Property.DeclaringType.FullName);
il.Emit(OpCodes.Ldstr, Property.FullName);
il.Emit(OpCodes.Call, Methods.PhpException.PropertyTypeMismatch);
il.MarkLabel(label_ok, true);
}
il.ReturnTemporaryLocal(strictness);
}
示例12: EmitLoadMethodInfo
/// <summary>
/// Emits load of <see cref="MethodInfo"/> onto the top of evaluation stack.
/// </summary>
/// <param name="il"></param>
/// <param name="mi"></param>
internal static void EmitLoadMethodInfo(ILEmitter/*!*/il, MethodInfo/*!*/mi/*, DelegateBuilder dbuild*/)
{
if (mi == null)
throw new ArgumentNullException("mi");
if (!mi.IsStatic)
throw new NotSupportedException();
// following code uses hack, where we can create delegate in "compile time", and then takes its MethodInfo property.
// new Func<...>( null, <mi> ).Method
//// construct the type
////var miArgs = mi.GetParameters(); // THIS FAILS WHEN <mi> IS NOT BAKED YET
////Type[] delegateArgs = new Type[1 + miArgs.Length];
////delegateArgs[0] = mi.ReturnType;
////for (int i = 0; i < miArgs.Length; i++) delegateArgs[i + 1] = miArgs[i].ParameterType;
//var delegateCtor = DelegateBuilder.GetDelegateCtor(dbuild.GetDelegateType(delegateArgs, il.GetNextUniqueIndex()));
var delegateCtor = DelegateBuilder.GetDelegateCtor(Types.Action[0]); // NOT NICE
//.ldnull
//.ldftn <mi>
//.newobj instance void Action::.ctor(object, native int)
//.call get_Method
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Ldftn, mi);
il.Emit(OpCodes.Newobj, delegateCtor);
il.Emit(OpCodes.Call, Properties.Delegate_Method.GetGetMethod());
}
示例13: EmitDeclareFunction
/// <summary>
/// Emits call to <see cref="ScriptContext.DeclareFunction"/>.
/// </summary>
internal static void EmitDeclareFunction(ILEmitter/*!*/il, IPlace/*!*/scriptContextPlace, PhpFunction/*!*/ function)
{
Label lbl_fieldinitialized = il.DefineLabel();
// private static PhpRoutine <routine>'function = null;
var attrs = FieldAttributes.Static | FieldAttributes.Private;
var field = il.TypeBuilder.DefineField(string.Format("<routine>'{0}", function.FullName), typeof(PhpRoutineDesc), attrs);
// if (<field> == null)
il.Emit(OpCodes.Ldsfld, field);
il.Emit(OpCodes.Brtrue, lbl_fieldinitialized);
{
// <field> = new PhpRoutineDesc(<attributes>, new RoutineDelegate(null, <delegate>))
// LOAD <attributes>;
il.LdcI4((int)function.MemberDesc.MemberAttributes);
// new RoutineDelegate(null, <delegate>, true)
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Ldftn, function.ArgLessInfo);
il.Emit(OpCodes.Newobj, Constructors.RoutineDelegate);
il.LoadBool(true);
// new PhpRoutineDesc:
il.Emit(OpCodes.Newobj, Constructors.PhpRoutineDesc_Attr_Delegate_Bool);
// <field> = <STACK>
il.Emit(OpCodes.Stsfld, field);
// new PurePhpFunction(<field>, fullName, argfull); // writes desc.Member
il.Emit(OpCodes.Ldsfld, field);
il.Emit(OpCodes.Ldstr, function.FullName);
CodeGenerator.EmitLoadMethodInfo(il, function.ArgFullInfo/*, AssemblyBuilder.DelegateBuilder*/);
il.Emit(OpCodes.Newobj, Constructors.PurePhpFunction);
il.Emit(OpCodes.Pop);
}
il.MarkLabel(lbl_fieldinitialized);
// CALL ScriptContent.DeclareFunction(<field>, <name>);
scriptContextPlace.EmitLoad(il);
// LOAD <field>
il.Emit(OpCodes.Ldsfld, field);
// LOAD <fullName>
il.Emit(OpCodes.Ldstr, function.FullName);
//
il.Emit(OpCodes.Call, Methods.ScriptContext.DeclareFunction);
}
示例14: EmitPhpException
internal void EmitPhpException(ILEmitter/*!*/ il, MethodInfo/*!*/ method)
{
// emits call to a method which reports an error:
il.Emit(OpCodes.Call, method);
// emits nop which makes sequence points working well in stack trace:
if (context.Config.Compiler.Debug)
il.Emit(OpCodes.Nop);
}
示例15: EmitOverrideStubsForPhpTemplate
/// <summary>
/// Emits stubs for one overridden or implemented PHP method.
/// </summary>
/// <param name="stubs">Already generated stubs.</param>
/// <param name="target">The overriding/implementing method.</param>
/// <param name="targetType">The type (perhaps constructed) that declared <paramref name="target"/>.</param>
/// <param name="declaringType">The type where the stubs should be emitted.</param>
/// <param name="template">The method being overridden/implemented (surely PHP).</param>
/// <param name="newSlot"><B>True</B> if the stub should be assigned a new vtable slot,
/// <B>false</B> otherwise.</param>
/// <remarks>
/// This method handles situations where method overriding/implementing does not work by itself because of
/// the fact that method names in PHP are case insensitive.
/// </remarks>
private void EmitOverrideStubsForPhpTemplate(IDictionary<string, MethodBuilder>/*!*/ stubs,
PhpMethod/*!*/ target, DType/*!*/ targetType, PhpType/*!*/ declaringType, DMemberRef/*!*/ template,
bool newSlot)
{
PhpMethod php_template = (PhpMethod)template.Member;
// Emit method stub if needed here ... (resolve .NET incompatibility of base method and overriding method)
//
// Until now, several possible cases or their combination are known:
// - base and overriding methods match, but their name letter-casing don't (need to define override explicitly to properly Bake the type)
// - base and overriding methods name match exactly, but overriding methods has additional arguments (with default values) (in PHP it is allowed) (stub needed)
// - ghost stub, where B extends A implements I, where A contains definition of method in I and casing does not match
//
// if signatures don't match, virtual sealed stub must be created, it only calls the target method
// if signatures match, only explicit override must be stated
if (target.Name.ToString() != php_template.Name.ToString() || // the names differ (perhaps only in casing)
target.Signature.ParamCount != php_template.Signature.ParamCount || // signature was extended (additional arguments added, with implicit value only)
target.Signature.AliasReturn != php_template.Signature.AliasReturn // returns PhpReference instead of Object
)
{
MethodInfo target_argfull = DType.MakeConstructed(target.ArgFullInfo, targetType as ConstructedType);
TypeBuilder type_builder = declaringType.RealTypeBuilder;
// we have to generate a pass-thru override stub that overrides the template based on
// name since it is impossible to install an explicit override of a method declared by
// a generic type in v2.0 SRE (feedback ID=97425)
bool sre_bug_workaround = (template.Type is ConstructedType);
if (target.DeclaringType == declaringType && !sre_bug_workaround &&
target.Signature.ParamCount == php_template.Signature.ParamCount &&
target.Signature.AliasReturn == php_template.Signature.AliasReturn)
{
// signatures match, just install an explicit override if possible
type_builder.DefineMethodOverride(target_argfull,
DType.MakeConstructed(php_template.ArgFullInfo, template.Type as ConstructedType));
}
else
{
string stubs_key = null;
MethodAttributes attrs;
if (sre_bug_workaround)
{
// check whether we have generated a stub having the template name before
if (stubs.ContainsKey(stubs_key = "," + php_template.ArgFullInfo.Name)) return;
attrs = php_template.ArgFullInfo.Attributes & ~MethodAttributes.Abstract;
}
else
{
attrs = MethodAttributes.PrivateScope | MethodAttributes.Virtual;
}
if (newSlot) attrs |= MethodAttributes.NewSlot;
else attrs &= ~MethodAttributes.NewSlot;
// determine stub return and parameters type
Type return_type;
Type[] param_types = php_template.Signature.ToArgfullSignature(1, out return_type);
param_types[0] = Types.ScriptContext[0];
MethodBuilder override_stub = type_builder.DefineMethod(
(sre_bug_workaround ? php_template.ArgFullInfo.Name : "<Override>"),
attrs, return_type, param_types);
ILEmitter il = new ILEmitter(override_stub);
//
// return target( [arg1, ...[, default, ...]] );
//
// pass-thru all arguments, including this (arg0)
int pass_args = Math.Min(param_types.Length, target.Signature.ParamCount + 1);
for (int i = 0; i <= pass_args; ++i) il.Ldarg(i); // this, param1, ....
for (int i = pass_args; i <= target.Signature.ParamCount; ++i)
{
// ... // PhpException.MissingArgument(i, target.FullName); // but in some override it can be optional argument
il.Emit(OpCodes.Ldsfld, PHP.Core.Emit.Fields.Arg_Default); // paramN
}
il.Emit(OpCodes.Callvirt, target_argfull);
// return
if (target.Signature.AliasReturn != php_template.Signature.AliasReturn)
il.Emit(OpCodes.Call, target.Signature.AliasReturn
? Methods.PhpVariable.Dereference // PhpVariable.Deference(obj)
//.........这里部分代码省略.........