当前位置: 首页>>代码示例>>C#>>正文


C# IPlace.EmitLoad方法代码示例

本文整理汇总了C#中IPlace.EmitLoad方法的典型用法代码示例。如果您正苦于以下问题:C# IPlace.EmitLoad方法的具体用法?C# IPlace.EmitLoad怎么用?C# IPlace.EmitLoad使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在IPlace的用法示例。


在下文中一共展示了IPlace.EmitLoad方法的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));
		}
开发者ID:tiaohai,项目名称:Phalanger,代码行数:26,代码来源:PhpStackBuilder.cs

示例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);
			}
		}
开发者ID:tiaohai,项目名称:Phalanger,代码行数:11,代码来源:PhpStackBuilder.cs

示例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);
			}
		}
开发者ID:tiaohai,项目名称:Phalanger,代码行数:22,代码来源:PhpStackBuilder.cs

示例4: EmitUnset

		internal override void EmitUnset(CodeGenerator/*!*/ codeGenerator, IPlace/*!*/ instance,
			ConstructedType constructedType, bool runtimeVisibilityCheck)
		{
			ILEmitter il = codeGenerator.IL;

			if (IsStatic)
			{
				// emit error (whether or not the property is visible):
				il.Emit(OpCodes.Ldstr, DeclaringType.FullName);
				il.Emit(OpCodes.Ldstr, this.FullName);
				codeGenerator.EmitPhpException(Methods.PhpException.StaticPropertyUnset);
				return;
			}

			// replace the field with a new PhpSmartReference with IsSet false
			instance.EmitLoad(il);
			il.Emit(OpCodes.Newobj, Constructors.PhpSmartReference.Void);
			il.Emit(OpCodes.Dup);
			
			il.LoadBool(false);
			il.Emit(OpCodes.Callvirt, Properties.PhpReference_IsSet.GetSetMethod());

			il.Emit(OpCodes.Stfld, DType.MakeConstructed(RealField, constructedType));
		}
开发者ID:tiaohai,项目名称:Phalanger,代码行数:24,代码来源:Properties.cs

示例5: EmitSet

		internal override AssignmentCallback EmitSet(CodeGenerator/*!*/ codeGenerator, IPlace instance, bool isRef,
			ConstructedType constructedType, bool runtimeVisibilityCheck)
		{
			Debug.Assert(IsStatic == (instance == null));

			AdjustConstructedType(ref constructedType);

			if (IsStatic)
			{
				// check the visibility at runtime by the operator:
				if (runtimeVisibilityCheck || UpgradesVisibility)
					return codeGenerator.EmitSetStaticPropertyOperator(DeclaringType, this.FullName, null, isRef);

				if (isRef)
				{
					if (!IsAppStatic) Implementor.EmitThreadStaticInit(codeGenerator, constructedType);

					// just write the PhpReference to the field upon assignment
					return delegate(CodeGenerator codeGen, PhpTypeCode stackTypeCode)
					{
						codeGen.IL.Emit(OpCodes.Stsfld, DType.MakeConstructed(RealField, constructedType));
					};
				}
				else
				{
					// read the PhpReference stored in the field
					EmitGetInternal(codeGenerator, null, true, constructedType, false, false);

					// finish the assignment by writing to its Value field
					return delegate(CodeGenerator codeGen, PhpTypeCode stackTypeCode)
					{
						codeGen.IL.Emit(OpCodes.Stfld, Fields.PhpReference_Value);
					};
				}
			}
			else
			{
				// direct access is possible, however, we have to be prepared for actually calling
				// the operator if the field proves to have been unset

				return delegate(CodeGenerator codeGen, PhpTypeCode stackTypeCode)
				{
					ILEmitter il = codeGen.IL;

					codeGen.EmitLoadSelf();
					instance.EmitLoad(il);
					il.Emit(isRef ? OpCodes.Ldflda : OpCodes.Ldfld, DType.MakeConstructed(RealField, constructedType));
					il.Emit(OpCodes.Ldstr, Name.ToString());
					codeGen.EmitLoadClassContext();

					if (isRef)
					{
						// CALL Operators.SetObjectFieldDirectRef(STACK,<target>,ref <field>,<field name>,<type desc>)
						il.Emit(OpCodes.Call, Methods.Operators.SetObjectFieldDirectRef);
					}
					else
					{
						// CALL Operators.SetObjectFieldDirect(STACK,<target>,<field>,<field name>,<type desc>)
						il.Emit(OpCodes.Call, Methods.Operators.SetObjectFieldDirect);
					}
				};
			}
		}
开发者ID:tiaohai,项目名称:Phalanger,代码行数:63,代码来源:Properties.cs

示例6: EmitNotNull

        /// <summary>
        /// Emits <c>place != null</c> expression.
        /// </summary>
        public void EmitNotNull(IPlace place)
        {
            Debug.Assert(place != null);
            Debug.Assert(place.TypeOpt.IsReferenceType);

            // {place} != null : boolean
            place.EmitLoad(_il);
            _il.EmitNullConstant();
            _il.EmitOpCode(ILOpCode.Cgt_un);
        }
开发者ID:iolevel,项目名称:peachpie,代码行数:13,代码来源:CodeGenerator.Emit.cs

示例7: 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&lt;T&gt;"/> 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);
            }
        }
开发者ID:hansdude,项目名称:Phalanger,代码行数:33,代码来源:ClrOverloadBuilder.cs

示例8: EmitGetEventObject

		internal void EmitGetEventObject(ILEmitter/*!*/ il, IPlace/*!*/ contextPlace, IPlace instance, bool dynamicStub)
		{
			// [ ClrEventObject<handlerType>.Wrap(<SC>, <event name>, <addMethod>, <removeMethod>) ]

			contextPlace.EmitLoad(il);
			il.Emit(OpCodes.Ldstr, FullName);

			ConstructorInfo hook_ctor = typeof(Library.EventClass<>.HookDelegate).MakeGenericType(HandlerType).
				GetConstructor(Types.DelegateCtorArgs);

			// create delegates to the add and remove methods
			EmitLoadAccessorDelegate(il, hook_ctor, instance, dynamicStub, AddMethod);
			EmitLoadAccessorDelegate(il, hook_ctor, instance, dynamicStub, RemoveMethod);

			MethodInfo wrap_method = typeof(Library.EventClass<>).MakeGenericType(HandlerType).GetMethod("Wrap");
			il.Emit(OpCodes.Call, wrap_method);
		}
开发者ID:tiaohai,项目名称:Phalanger,代码行数:17,代码来源:Properties.cs

示例9: EmitGet

		internal override PhpTypeCode EmitGet(CodeGenerator/*!*/ codeGenerator, IPlace instance, bool wantRef,
			ConstructedType constructedType, bool runtimeVisibilityCheck)
		{
			Debug.Assert(IsStatic == (instance == null));

			ILEmitter il = codeGenerator.IL;

			if (IsStatic)
			{
				if (runtimeVisibilityCheck)
				{
					// let the operator to check the visibility:
					return codeGenerator.EmitGetStaticPropertyOperator(DeclaringType, this.FullName, null, wantRef);
				}
				il.Emit(OpCodes.Ldsfld, fieldInfo);
			}
			else
			{
				instance.EmitLoad(il);
				il.Emit(OpCodes.Ldfld, fieldInfo);
			}

			PhpTypeCode result = ClrOverloadBuilder.EmitConvertToPhp(il, fieldInfo.FieldType/*, codeGenerator.ScriptContextPlace*/);

			codeGenerator.EmitReferenceDereference(ref result, wantRef);
			return result;
		}
开发者ID:tiaohai,项目名称:Phalanger,代码行数:27,代码来源:Properties.cs

示例10: EmitOverloadCall

		/// <summary>
		/// Emits call to specified overload.
		/// </summary>
		/// <param name="method">The overload implementor.</param>
		/// <param name="ps">Formal parameters of the <paramref name="method"/>.</param>
		/// <param name="phpParamCount">The number of PHP arguments of the overload.</param>
        /// <param name="scriptContext">A place where current script context should be loaded from.</param>
		/// <param name="rtVariables">A place where run-time variables table should be loaded from.</param>
		/// <param name="namingContext">A place where the naming can be load from.</param>
        /// <param name="classContext">A place where the class context can be load from.</param>
		/// <param name="optArgs">A place where the number of optional arguments should be loaded from.</param>
		/// <param name="selfRef">A place where reference to 'self' ($this) can be loaded from.</param>
        /// <param name="ignoringReturnValue">True if the return value of the function call is not used then.</param>
		/// <returns>A type of value stored on the top of the evaluation stack. In case of value type, it is NOT boxed.</returns>
		public Type EmitOverloadCall(
			MethodInfo method,
			ParameterInfo[] ps,
			int phpParamCount,
            IPlace scriptContext,
			IPlace rtVariables,
			IPlace namingContext,
            IPlace classContext,
			IPlace optArgs,
			IPlace selfRef,
            bool ignoringReturnValue)
		{
			pushedArgsCount = 0;

            Label overloadCallEndLabel = il.DefineLabel();
            Type/*!*/return_type = method.ReturnType;

            // the routine used to skip the method call in case of invalid parameter cast
            overloadCallSkipEmitter = (ile) =>
                {
                    if (return_type != Types.Void)
                    {
                        // emit the value; because the method call was skipped, value must be loaded here
                        if (return_type.IsValueType)
                            ile.LoadLiteral(Activator.CreateInstance(return_type), false);    // value is not boxed
                        else
                            ile.Emit(OpCodes.Ldnull);
                    }

                    // goto the end label
                    il.Emit(OpCodes.Br, overloadCallEndLabel);
                };

            if (scriptContext != null)
            {
                // LOAD(<context>);
                scriptContext.EmitLoad(il);
                pushedArgsCount++;
            }

			if (selfRef != null)
			{
				// LOAD(<this>);
				selfRef.EmitLoad(il);
				pushedArgsCount++;
			}

			if (rtVariables != null)
			{
				// LOAD(<defined variables>);
				rtVariables.EmitLoad(il);
				pushedArgsCount++;
			}

			if (namingContext != null)
			{
				// LOAD(<naming context>);
				namingContext.EmitLoad(il);
				pushedArgsCount++;
			}

            if (classContext != null)
            {
                // LOAD(<class_context>)
                classContext.EmitLoad(il);
                pushedArgsCount++;
            }

			// loads mandatory arguments:
			for (int i = 0; i < phpParamCount; i++)
			{
				EmitMandatoryArgumentLoad(i, ps[pushedArgsCount]);
				pushedArgsCount++;
			}

			// loads optional arguments:
			if (optArgs != null)
			{
				loadOptParams(this, phpParamCount, ps[ps.Length - 1], optArgs);
				pushedArgsCount++;
			}

			Debug.Assert(pushedArgsCount == ps.Length);

			// all class library functions are args-unaware => remove frame if using stack:
			if (stack != null)
//.........这里部分代码省略.........
开发者ID:proff,项目名称:Phalanger,代码行数:101,代码来源:OverloadsBuilder.cs

示例11: EmitPeekAllArguments

		/// <summary>
		/// Emits load of an array where all optional arguments are stored.
		/// Each optional argument is peeked from the PHP stack and converted before stored to the array.
		/// The resulting array is pushed on evaluation stack so it can be later passed as an argument to a method.
		/// </summary>
		/// <param name="builder">The builder.</param>
		/// <param name="start">The index of the first argument to be loaded.</param>
		/// <param name="param">The last parameter of the overload (should be an array).</param>
		/// <param name="optArgCount">The place where the number of optional arguments is stored.</param>
		/// <remarks>Assumes that the non-negative number of optional arguments has been stored to 
		/// <paramref name="optArgCount"/> place.</remarks>
		public static void EmitPeekAllArguments(OverloadsBuilder/*!*/ builder, int start, ParameterInfo param, IPlace optArgCount)
		{
			Debug.Assert(start >= 0 && optArgCount != null && param != null);

			ILEmitter il = builder.IL;
			Type elem_type = param.ParameterType.GetElementType();
			Type array_type = Type.GetType(elem_type.FullName + "[]", true);
			Type actual_type;

			// declares aux. variables:
			LocalBuilder loc_array = il.DeclareLocal(array_type);
			LocalBuilder loc_i = il.DeclareLocal(typeof(int));
			LocalBuilder loc_elem = il.DeclareLocal(elem_type);

			// creates an array for the arguments 
			// array = new <elem_type>[opt_arg_count]:
			optArgCount.EmitLoad(il);
			il.Emit(OpCodes.Newarr, elem_type);
			il.Stloc(loc_array);

			Label for_end_label = il.DefineLabel();
			Label condition_label = il.DefineLabel();

			// i = 0;
			il.Emit(OpCodes.Ldc_I4_0);
			il.Stloc(loc_i);

			// FOR (i = 0; i < opt_arg_count; i++)
			if (true)
			{
				il.MarkLabel(condition_label);

				// condition (i < opt_arg_count):
				il.Ldloc(loc_i);
				optArgCount.EmitLoad(il);
				il.Emit(OpCodes.Bge, for_end_label);

				// LOAD stack, i + start+1>:
				builder.Stack.EmitLoad(il);
				il.Ldloc(loc_i);
				il.LdcI4(start + 1);
				il.Emit(OpCodes.Add);

				if (elem_type == typeof(PhpReference))
				{
					// CALL stack.PeekReferenceUnchecked(STACK);
					il.Emit(OpCodes.Call, Methods.PhpStack.PeekReferenceUnchecked);
					actual_type = typeof(PhpReference);
				}
				else
				{
					// CALL stack.PeekValueUnchecked(STACK);
					il.Emit(OpCodes.Call, Methods.PhpStack.PeekValueUnchecked);
					actual_type = typeof(object);
				}

				// emits a conversion stuff (loads result into "elem" local variable):
				builder.EmitArgumentConversion(elem_type, actual_type, false, param);
				il.Stloc(loc_elem);

				// array[i] = elem;
				il.Ldloc(loc_array);
				il.Ldloc(loc_i);
				il.Ldloc(loc_elem);
				il.Stelem(elem_type);

				// i = i + 1;
				il.Ldloc(loc_i);
				il.Emit(OpCodes.Ldc_I4_1);
				il.Emit(OpCodes.Add);
				il.Stloc(loc_i);

				// GOTO condition;
				il.Emit(OpCodes.Br, condition_label);
			}
			// END FOR

			il.MarkLabel(for_end_label);

			// loads array to stack - consumed by the method call:
			il.Ldloc(loc_array);
		}
开发者ID:tiaohai,项目名称:Phalanger,代码行数:93,代码来源:PhpStackBuilder.cs

示例12: EmitReferencePeekUnchecked

		public static object EmitReferencePeekUnchecked(ILEmitter/*!*/ il, IPlace/*!*/ stack, IPlace/*!*/ index)
		{
			Debug.Assert(il != null && stack != null && index != null);

			// LOAD stack.PeekReferenceUnchecked(<index+1>);
			stack.EmitLoad(il);
			index.EmitLoad(il);
			il.Emit(OpCodes.Call, Methods.PhpStack.PeekReferenceUnchecked);

			return typeof(PhpReference);
		}
开发者ID:tiaohai,项目名称:Phalanger,代码行数:11,代码来源:PhpStackBuilder.cs

示例13: EmitValuePeek

		//public static MethodCallPlace/*!*/ MakePeekValuePlace(IPlace/*!*/ stack, IPlace/*!*/ index)
		//{
		//  Debug.Assert(stack != null && index != null);
		//  return new MethodCallPlace(Methods.PhpStack.PeekValue, false, stack, index);
		//}

		//public static MethodCallPlace/*!*/ MakeValuePeekUncheckedPlace(IPlace/*!*/ stack, IPlace/*!*/ index)
		//{
		//  Debug.Assert(stack != null && index != null);
		//  return new MethodCallPlace(Methods.PhpStack.PeekValueUnchecked, false, stack, index);
		//}

		//public static MethodCallPlace/*!*/ MakeReferencePeekPlace(IPlace/*!*/ stack, IPlace/*!*/ index)
		//{
		//  Debug.Assert(stack != null && index != null);
		//  return new MethodCallPlace(Methods.PhpStack.PeekReference, false, stack, index);
		//}

		//public static MethodCallPlace/*!*/ MakeReferencePeekUncheckedPlace(IPlace/*!*/ stack, IPlace/*!*/ index)
		//{
		//  Debug.Assert(stack != null && index != null);
		//  return new MethodCallPlace(Methods.PhpStack.PeekReferenceUnchecked, false, stack, index);
		//}


		public static object EmitValuePeek(ILEmitter/*!*/ il, IPlace/*!*/ stack, IPlace/*!*/ index)
		{
			Debug.Assert(il != null && stack != null && index != null);

			// CALL stack.PeekValue(<index+1>);
			stack.EmitLoad(il);
			index.EmitLoad(il);
			il.Emit(OpCodes.Call, Methods.PhpStack.PeekValue);

			return typeof(object);
		}
开发者ID:tiaohai,项目名称:Phalanger,代码行数:36,代码来源:PhpStackBuilder.cs

示例14: EmitLoadInstanceUnwrapped

        /// <summary>
        /// Emit load <paramref name="instance"/> in top of the evaluation stack. Unwraps the value if &lt;proxy&gt; is used instead of <c>this</c>.
        /// </summary>
        /// <param name="codeGenerator"></param>
        /// <param name="instance"></param>
        private static void EmitLoadInstanceUnwrapped(CodeGenerator/*!*/ codeGenerator, IPlace instance)
        {
            if (instance != null)
            {
                // just detect DirectVarUse holding $this in context of Type with <proxy> property:
                var targetExpression = ExpressionPlace.GetExpression(instance);

                // pass RealObject instead of DObject when using <proxy>:   // J: ASP.NET code behind fix // ArgLesses expect RealObject too
                if (targetExpression != null &&
                    codeGenerator.LocationStack.InMethodDecl && codeGenerator.LocationStack.PeekMethodDecl().Type.ProxyFieldInfo != null &&    // current type has "<proxy>" property
                    targetExpression is DirectVarUse && ((DirectVarUse)targetExpression).VarName.IsThisVariableName && ((DirectVarUse)targetExpression).IsMemberOf == null)   // we are accessing "this"
                    instance = IndexedPlace.ThisArg;    // "this" instead of "this.<proxy>"

                //
                instance.EmitLoad(codeGenerator.IL);
            }
        }
开发者ID:tiaohai,项目名称:Phalanger,代码行数:22,代码来源:Methods.cs

示例15: EmitGetProperty

        /// <summary>
        /// Create and call <see cref="CallSite"/> for getting property.
        /// </summary>
        /// <param name="cg"><see cref="CodeGenerator"/>.</param>
        /// <param name="wantRef">Wheter <see cref="PhpReference"/> is expected as the result.</param>
        /// <param name="targetExpr">The expression representing the target (object).</param>
        /// <param name="targetObjectPlace">The place representing the target (<see cref="DObject"/>) iff <paramref name="targetExpr"/> is not provided.</param>
        /// <param name="targetPlace">The place representing the target (object) iff <paramref name="targetExpr"/> and <paramref name="targetObjectPlace"/> are not provided.</param>
        /// <param name="targetType">Type of target iff we are getting property statically.</param>
        /// <param name="fieldName">The name of the field. Can be null if the name is not known at compile time (indirect).</param>
        /// <param name="fieldNameExpr">The expression used to get field name in run time (iff <paramref name="fieldName"/> is <c>null</c>.</param>
        /// <param name="issetSemantics">Wheter we are only checking if the property exists. If true, no warnings are thrown during run time.</param>
        /// <returns>Type code of the value that is pushed onto the top of the evaluation stack.</returns>
        public PhpTypeCode EmitGetProperty(
            PHP.Core.CodeGenerator/*!*/cg, bool wantRef,
            Expression targetExpr, IPlace targetObjectPlace, IPlace targetPlace, DType targetType,
            string fieldName, Expression fieldNameExpr,
            bool issetSemantics)
        {
            Debug.Assert(fieldName != null ^ fieldNameExpr != null);
            Debug.Assert(targetExpr != null || targetObjectPlace != null || targetPlace != null || targetType != null);
            
            //
            bool staticCall = (targetExpr == null && targetObjectPlace == null && targetPlace == null); // we are going to access static property
            bool fieldNameIsKnown = (fieldName != null);
            bool classContextIsKnown = (this.classContextPlace != null);

            //
            // binder flags:
            //
            Type returnType = wantRef ? Types.PhpReference[0] : Types.Object[0];
            
            //
            // define the call site:
            //

            //
            List<Type> additionalArgs = new List<Type>();
            if (!classContextIsKnown) additionalArgs.Add(Types.DTypeDesc[0]);
            if (!fieldNameIsKnown) additionalArgs.Add(Types.String[0]);

            var delegateTypeArgs = GetPropertyDelegateTypeArgs(
                staticCall ? Types.DTypeDesc[0] : ((targetObjectPlace != null) ? Types.DObject[0] : Types.Object[0]),   // DTypeDesc of static field's declaring type || DObject if field called on DObject known at compile time || otherwise object
                additionalArgs.ToArray(),
                returnType);

            var delegateType = /*System.Linq.Expressions.Expression.*/delegateBuilder.GetDelegateType(delegateTypeArgs, callSitesCount);    // (J) do not create dynamic delegates in dynamic modules, so they can be referenced from non-transient assemblies

            //
            var field = DefineCallSite(cg.IL, string.Format("get{0}_{1}", wantRef ? "ref" : string.Empty, fieldName ?? "$"), delegateType, (il) =>
            {
                // <LOAD> Binder.{GetProperty|GetStaticProperty}( fieldName, classContext, issetSemantics, <returnType> )
                if (fieldName != null) il.Emit(OpCodes.Ldstr, fieldName); else il.Emit(OpCodes.Ldnull);
                if (this.classContextPlace != null) this.classContextPlace.EmitLoad(il); else il.Emit(OpCodes.Ldsfld, Fields.UnknownTypeDesc.Singleton);
                il.LoadBool(issetSemantics);

                il.Emit(OpCodes.Ldtoken, returnType);
                il.Emit(OpCodes.Call, Methods.GetTypeFromHandle);

                il.Emit(OpCodes.Call, staticCall ? Methods.Binder.StaticGetProperty : Methods.Binder.GetProperty);
            });

            //
            // call the CallSite:
            //

            // <field>.Target( <field>, <targetExpr|targetType>, (classContext)?, <methodNameExpr>? ):

            cg.IL.Emit(OpCodes.Ldsfld, field);
            cg.IL.Emit(OpCodes.Ldfld, field.FieldType.GetField("Target"));
            cg.IL.Emit(OpCodes.Ldsfld, field);
            if (staticCall) targetType.EmitLoadTypeDesc(cg, ResolveTypeFlags.UseAutoload | ResolveTypeFlags.ThrowErrors);
            else if (targetExpr != null)
            {
                cg.ChainBuilder.Lengthen(); // for hop over ->
                cg.EmitBoxing(targetExpr.Emit(cg)); // prepare for operator invocation
            }
            else if (targetObjectPlace != null) targetObjectPlace.EmitLoad(cg.IL);
            else if (targetPlace != null) targetPlace.EmitLoad(cg.IL);
            else Debug.Fail();
            if (!classContextIsKnown) cg.EmitLoadClassContext();
            if (!fieldNameIsKnown) cg.EmitName(fieldName/*null*/, fieldNameExpr, true, PhpTypeCode.String);

            cg.MarkTransientSequencePoint();
            cg.IL.Emit(OpCodes.Callvirt, delegateType.GetMethod("Invoke"));

            cg.MarkTransientSequencePoint();
            
            //
            return PhpTypeCodeEnum.FromType(returnType);
        }
开发者ID:Ashod,项目名称:Phalanger,代码行数:91,代码来源:CallSitesBuilder.cs


注:本文中的IPlace.EmitLoad方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。