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


C# Expression.Emit方法代码示例

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


在下文中一共展示了Expression.Emit方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。

示例1: EmitArrayKey

		internal PhpTypeCode EmitArrayKey(ChainBuilder chain, Expression key)
		{
			PhpTypeCode result;

			if (key != null)
			{
				if (chain != null) chain.Create();
				
                // convert the key into integer if necessary and possible in compile time
                IntStringKey array_key;
                if (key.HasValue() && Convert.ObjectToArrayKey(key.GetValue(), out array_key) && array_key.IsInteger)
                {
                    il.LdcI4(array_key.Integer);
                    result = PhpTypeCode.Integer;
                }
                else
                {
                    // Emit index and box the result
                    switch (result = key.Emit(this))
                    {
                        case PhpTypeCode.Integer:
                            break;

                        case PhpTypeCode.String:
                            break;

                        default:
                            EmitBoxing(result);
                            result = PhpTypeCode.Object;
                            break;
                    }
                }
				
				if (chain != null) chain.End();
			}
			else
				result = PhpTypeCode.Invalid;

			return result;
		}
开发者ID:dw4dev,项目名称:Phalanger,代码行数:40,代码来源:CodeGenerator.cs

示例2: EmitObjectToBoolean

        /// <summary>
        /// Emits conversion to boolean.
        /// </summary>
        /// <param name="expr">Expression to be converted.</param>
        /// <param name="negation">Whether the result should be logic negation of original conversion.</param>
        internal void EmitObjectToBoolean(Expression/*!*/expr, bool negation)
        {
            // <expr>
            var typecode = expr.Emit(this);

            //
            switch (typecode)
            {
                case PhpTypeCode.Boolean:
                    if (negation)
                        this.EmitLogicNegation();
                    break;

                case PhpTypeCode.Integer:
                    // <int> != 0
                    this.EmitLogicNegation();
                    if (!negation)
                        this.EmitLogicNegation();
                    break;

                case PhpTypeCode.LongInteger:
                    // <long> != 0
                    il.Emit(OpCodes.Ldc_I4_0);
                    il.Emit(OpCodes.Conv_I8);
					il.Emit(OpCodes.Ceq);
                    if (!negation)
                        this.EmitLogicNegation();
                    break;

                case PhpTypeCode.Double:
                    // <double> != 0.0
                    il.Emit(OpCodes.Ldc_R8, 0.0);
                    il.Emit(OpCodes.Ceq);
                    if (!negation)
                        this.EmitLogicNegation();
                    break;

                case PhpTypeCode.Void:
                    if (negation)
                        il.Emit(OpCodes.Ldc_I4_1);
                    else
                        il.Emit(OpCodes.Ldc_I4_0);
                    break;

                case PhpTypeCode.String:
                    // StringToBoolean( <string> )
                    IL.Emit(OpCodes.Call, Methods.Convert.StringToBoolean);
                    if (negation)
                        this.EmitLogicNegation();
                    break;

                default:
                    // ObjectToBoolean( (object)<expr> )
                    EmitBoxing(typecode);
                    IL.Emit(OpCodes.Call, Methods.Convert.ObjectToBoolean);
                    if (negation)
                        this.EmitLogicNegation();
                    break;
            }
        }
开发者ID:dw4dev,项目名称:Phalanger,代码行数:65,代码来源:CodeGenerator.cs

示例3: EmitConversion

		/// <summary>
		/// Emits IL instructions that convert the top of evaluation stack to a specified type.
		/// </summary>
		/// <remarks>
		/// Emits a call to one of <see cref="PHP.Core.Convert"/> methods to do the conversion.
		/// The method result is left on the evaluation stack.
		/// </remarks>
		internal void EmitConversion(Expression/*!*/ expression, PhpTypeCode dst)
		{
			// expression is evaluable:
			if (expression.HasValue())
			{
				switch (dst)
				{
					case PhpTypeCode.String:
						il.Emit(OpCodes.Ldstr, PHP.Core.Convert.ObjectToString(expression.GetValue()));
						break;

					case PhpTypeCode.Boolean:
                        il.LdcI4(PHP.Core.Convert.ObjectToBoolean(expression.GetValue()) ? 1 : 0);
						break;

					case PhpTypeCode.Integer:
                        il.LdcI4(PHP.Core.Convert.ObjectToInteger(expression.GetValue()));
						break;

					case PhpTypeCode.Double:
                        il.Emit(OpCodes.Ldc_R8, PHP.Core.Convert.ObjectToDouble(expression.GetValue()));
						break;

					case PhpTypeCode.Object:
                        il.LoadLiteral(expression.GetValue());
						break;

					default:
						Debug.Fail("Conversion not implemented.");
						break;
				}
			}
			else
			{
				// emits the expression:
				PhpTypeCode src = expression.Emit(this);

				// emits no conversion if types are the same:
				if (src == dst) return;

				// emits boxing if needed (conversion methods takes object):
				EmitBoxing(src);

				switch (dst)
				{
					case PhpTypeCode.String:
						il.Emit(OpCodes.Call, Methods.Convert.ObjectToString);
						break;

					case PhpTypeCode.Boolean:
						il.Emit(OpCodes.Call, Methods.Convert.ObjectToBoolean);
						break;

					case PhpTypeCode.Integer:
						il.Emit(OpCodes.Call, Methods.Convert.ObjectToBoolean);
						break;

					case PhpTypeCode.Double:
						il.Emit(OpCodes.Call, Methods.Convert.ObjectToDouble);
						break;

					case PhpTypeCode.Object:
						// nop //
						break;

					default:
						Debug.Fail("Conversion is not implemented.");
						break;
				}
			}
		}
开发者ID:dw4dev,项目名称:Phalanger,代码行数:78,代码来源:CodeGenerator.cs

示例4: EmitEval

        /// <summary>
        /// Emit call to <see cref="DynamicCode.Assert"/> or <see cref="DynamicCode.Eval"/>.
        /// </summary>
        internal PhpTypeCode EmitEval(EvalKinds kind, Expression/*!*/code, Text.Span span, QualifiedName? currentNamespace, Dictionary<string, QualifiedName> currentAliases)
        {
            Debug.Assert(code != null);

            // LOAD DynamicCode.<Eval | Assert>(<code>, context, definedVariables, self, includer, source, line, column, evalId, naming)
            if (kind == EvalKinds.Assert)
            {
                // an argument of the assert is boxed:
                EmitBoxing(code.Emit(this));
            }
            else if (kind == EvalKinds.SyntheticEval)
            {
                Debug.Assert(code.HasValue());
                Debug.Assert(code.GetValue() is string);

                // an argument of the eval is converted to a string:
                il.Emit(OpCodes.Ldstr, (string)code.GetValue());
                il.Emit(OpCodes.Ldc_I4_1);
            }
            else
            {
                // an argument of the eval is converted to a string:
                EmitConversion(code, PhpTypeCode.String);
                il.Emit(OpCodes.Ldc_I4_0);
            }

            var position = new Text.TextPoint(this.SourceUnit.LineBreaks, span.Start);

            EmitLoadScriptContext();
            EmitLoadRTVariablesTable();
            EmitLoadSelf();
            EmitLoadClassContext();
            EmitEvalInfoPass(position.Line, position.Column);
            EmitNamingContext(currentNamespace, currentAliases, span.Start);

            il.Emit(OpCodes.Call, (kind == EvalKinds.Assert) ? Methods.DynamicCode.Assert : Methods.DynamicCode.Eval);

            return (kind == EvalKinds.Assert) ? PhpTypeCode.Boolean : PhpTypeCode.Object;
        }
开发者ID:dw4dev,项目名称:Phalanger,代码行数:42,代码来源:CodeGenerator.cs

示例5: EmitEcho

		/// <summary>
		/// Emits IL instructions to process the <B>echo</B> and <B>print</B> commands.
		/// </summary>
		/// <param name="parameter">Expression to be sent to output.</param>
		public void EmitEcho(Expression parameter)
		{
			// Template:
			//	context.Echo(value);

			ConcatEx concat;
			//BinaryEx binary_expr;

			if ((concat = parameter as ConcatEx) != null && concat.Expressions.Length > 1)
			{
                //foreach (Expression expr in concat.Expressions)
                //{
                //    EmitLoadScriptContext();
                //    EmitEchoCall(expr.Emit(this));
                //}

				// obsolete: (but expressions must be first emitted and processed, then echoed)
                // array = new object[] { expr1, expr2, ..., exprn };
                //LocalBuilder array = EmitObjectArrayPopulation(concat.Expressions, null);

                //// context.Echo(array);
                //EmitLoadScriptContext();
                //il.Ldloc(array);
                //il.Emit(OpCodes.Call, Methods.ScriptContext.Echo.ObjectArray);

                EmitEcho(concat.Expressions);
			}
            //// obsolete: wrong order of expressions execution (evaluate first, then echo!)
            //else if ((binary_expr = parameter as BinaryEx) != null && binary_expr.Operation == Operations.Concat)
            //{
            //    // context.Echo(<left>)
            //    EmitLoadScriptContext();
            //    EmitEchoCall(binary_expr.LeftExpr.Emit(this));

            //    // context.Echo(<right>)
            //    EmitLoadScriptContext();
            //    EmitEchoCall(binary_expr.RightExpr.Emit(this));
            //}
			else
			{
                var typecode = parameter.Emit(this);
				EmitLoadScriptContext();
                // CALL ScriptContext.Echo(<parameter>, <context>)
                EmitEchoStaticCall(typecode);
			}
		}
开发者ID:dw4dev,项目名称:Phalanger,代码行数:50,代码来源:CodeGenerator.cs

示例6: EmitRoutineOperatorCall

		/// <summary>
		/// Emits a call to a routine with specified name using an operator.
		/// </summary>
        internal PhpTypeCode EmitRoutineOperatorCall(DType type, Expression targetExpr,
            string routineFullName, string fallbackRoutineFullname, Expression routineNameExpr, CallSignature callSignature, AccessType access)
        {
            Debug.Assert(routineFullName != null ^ routineNameExpr != null);

            MethodInfo operator_method;
            PhpTypeCode return_type_code;

            // (J) use call sites to call the method:
            if (targetExpr != null /*|| type != null*/)
            {
                Debug.Assert(fallbackRoutineFullname == null);

                return this.CallSitesBuilder.EmitMethodCall(this, CallSitesBuilder.AccessToReturnType(access), targetExpr, type, routineFullName, routineNameExpr, callSignature);
            }
            else if (targetExpr != null)
            {
                Debug.Assert(fallbackRoutineFullname == null);

                // LOAD Operators.InvokeMethod(<target>, <method name>, <type desc>, <context>);

                // start a new operators chain (as the rest of chain is read)
                this.ChainBuilder.Create();
                this.ChainBuilder.Begin();
                this.ChainBuilder.Lengthen(); // for hop over ->

                // prepare for operator invocation
                this.EmitBoxing(targetExpr.Emit(this));
                this.ChainBuilder.End();

                this.EmitName(routineFullName, routineNameExpr, true);
                this.EmitLoadClassContext();
                this.EmitLoadScriptContext();

                if (routineFullName != null)
                    operator_method = Methods.Operators.InvokeMethodStr;
                else
                    operator_method = Methods.Operators.InvokeMethodObj;

                return_type_code = PhpTypeCode.PhpReference;
            }
            else if (type != null)
            {
                Debug.Assert(fallbackRoutineFullname == null);

                // LOAD Operators.InvokeStaticMethod(<type desc>, <method name>, <self>, <type desc>, context);
                type.EmitLoadTypeDesc(this, ResolveTypeFlags.UseAutoload | ResolveTypeFlags.ThrowErrors);

                this.EmitName(routineFullName, routineNameExpr, true);

                this.EmitLoadSelf();
                this.EmitLoadClassContext();
                this.EmitLoadScriptContext();

                operator_method = Methods.Operators.InvokeStaticMethod;
                return_type_code = PhpTypeCode.PhpReference;
            }
            else
            {
                Debug.Assert(routineNameExpr == null || fallbackRoutineFullname == null);   // (routineNameExpr != null) => (fallbackRoutineFullName == null)

                // DRoutineDesc <callHint>;
                FieldInfo hintField = this.CallSitesBuilder.DefineField(
                    "<callHint>'" + (routineFullName ?? "indirect"),
                    typeof(PHP.Core.Reflection.DRoutineDesc),
                    FieldAttributes.Static | FieldAttributes.Assembly);

                // LOAD ScriptContext.Call{|Void|Value}(<local variables>, <naming context>, <function name>, ref <hint>, context);
                this.EmitLoadRTVariablesTable();
                this.EmitLoadNamingContext();
                this.EmitName(routineFullName, routineNameExpr, true);
                if (fallbackRoutineFullname != null) il.Emit(OpCodes.Ldstr, fallbackRoutineFullname); else il.Emit(OpCodes.Ldnull); // fallback fcn name
                il.Emit(OpCodes.Ldsflda, hintField);
                this.EmitLoadScriptContext();

                // (J) only necessary copying, dereferencing or reference making:
                if (access == AccessType.None)
                {
                    operator_method = Methods.ScriptContext.CallVoid;
                    return_type_code = PhpTypeCode.Void;
                }
                else if (access == AccessType.Read)
                {
                    operator_method = Methods.ScriptContext.CallValue;
                    return_type_code = PhpTypeCode.Object;
                }
                else
                {
                    operator_method = Methods.ScriptContext.Call;
                    return_type_code = PhpTypeCode.PhpReference;
                }
            }

            // emits load of parameters to the PHP stack:
            callSignature.EmitLoadOnPhpStack(this);

            // marks transient sequence point just before the call:
//.........这里部分代码省略.........
开发者ID:dw4dev,项目名称:Phalanger,代码行数:101,代码来源:CodeGenerator.cs

示例7: EmitEnsureStaticProperty

		/// <summary>
		/// Emits IL instructions that ensure that a static field is of <see cref="PhpObject"/> or <see cref="PhpArray"/>
		/// type. Handles the case when field name is unknown at compile time (see <see cref="AST.IndirectStFldUse"/>).
		/// </summary>
        /// <param name="typeRef">The class name (identifier index).</param>
		/// <param name="propertyName">The property name.</param>
		/// <param name="propertyNameExpr">The expression that evaluates to property name.</param>
		/// <param name="ensureArray">Whether to ensure that static field is an array (or an object).</param>
		/// <remarks>
		/// Nothing is expected on the evaluation stack. A <see cref="PhpArray"/> or <see cref="DObject"/> is left on the
		/// evaluation stack.
		/// </remarks>
		public PhpTypeCode EmitEnsureStaticProperty(TypeRef typeRef, VariableName? propertyName,
			Expression propertyNameExpr, bool ensureArray)
		{
			Debug.Assert(propertyName != null ^ propertyNameExpr != null);

			ResolveTypeFlags flags = ResolveTypeFlags.UseAutoload | ResolveTypeFlags.ThrowErrors;

			// LOAD Operators.EnsureStaticFieldIs[Object|Array](<type desc>, <field name>, <type desc>, <context>)
            typeRef.EmitLoadTypeDesc(codeGenerator, flags);

			if (propertyNameExpr != null)
				codeGenerator.EmitBoxing(propertyNameExpr.Emit(codeGenerator));
			else
				codeGenerator.IL.Emit(OpCodes.Ldstr, propertyName.Value.ToString());

			codeGenerator.EmitLoadClassContext();
			codeGenerator.EmitLoadScriptContext();

			if (ensureArray)
				codeGenerator.IL.Emit(OpCodes.Call, Methods.Operators.EnsureStaticPropertyIsArray);
			else
				codeGenerator.IL.Emit(OpCodes.Call, Methods.Operators.EnsureStaticPropertyIsObject);

			EmitErrorCheck(ensureArray);
			return (ensureArray) ? PhpTypeCode.PhpArray : PhpTypeCode.DObject;
		}
开发者ID:dw4dev,项目名称:Phalanger,代码行数:38,代码来源:Chains.cs

示例8: EmitEnsureItem

		/// <summary>
		/// Emits IL instructions that ensure that the specified item of specified array is of
		/// type <see cref="PhpArray"/>.
		/// </summary>
		/// <param name="array">Array which item is examined.</param>
		/// <param name="index">Index determining the item which should be examined (can be <B>null</B>).</param>
		/// <param name="ensureArray">Whether to ensure that static field is an array (or an object).</param>
		/// <remarks>
		/// This method is used in operators chains. Nothing is expected on the evaluation stack. 
		/// If the item is of type <see cref="PhpArray"/> and <see cref="PhpObject"/> (respectively) 
		/// it is left on the evaluation stack. Otherwise the control is transfered to the end of chain.
		/// </remarks>
		public PhpTypeCode EmitEnsureItem(Expression/*!*/ array, Expression index, bool ensureArray)
		{
			if (!ensureArray) Lengthen();

			array.Emit(codeGenerator);

			if (index != null)
			{
				// keyed item:
				Create();
				codeGenerator.EmitBoxing(index.Emit(codeGenerator));
				End();

				if (ensureArray)
				{
					codeGenerator.IL.Emit(OpCodes.Callvirt, Methods.PhpArray.EnsureItemIsArray_Object);
				}
				else
				{
					codeGenerator.EmitLoadScriptContext();
					codeGenerator.IL.Emit(OpCodes.Callvirt, Methods.PhpArray.EnsureItemIsObject_Object);
				}
			}
			else
			{
				// key-less item:
				if (ensureArray)
				{
					codeGenerator.IL.Emit(OpCodes.Callvirt, Methods.PhpArray.EnsureItemIsArray);
				}
				else
				{
					codeGenerator.EmitLoadScriptContext();
					codeGenerator.IL.Emit(OpCodes.Callvirt, Methods.PhpArray.EnsureItemIsObject);
				}
			}
			EmitErrorCheck(ensureArray);
			return (ensureArray) ? PhpTypeCode.PhpArray : PhpTypeCode.DObject;
		}
开发者ID:dw4dev,项目名称:Phalanger,代码行数:51,代码来源:Chains.cs

示例9: EmitUnsetItem

		public void EmitUnsetItem(Expression array, Expression index)
		{
			// Template:
			//		void UnsetItem(object var,object index)

			array.Emit(codeGenerator);

			Debug.Assert(index != null);

			Create();
			codeGenerator.EmitBoxing(index.Emit(codeGenerator));
			End();

			codeGenerator.IL.Emit(OpCodes.Call, Methods.Operators.UnsetItem);
		}
开发者ID:dw4dev,项目名称:Phalanger,代码行数:15,代码来源:Chains.cs

示例10: EmitGetItem

		/// <summary>
		/// Emits IL instructions that load the value of an item of given array.
		/// </summary>
		/// <param name="array"><see cref="Expression"/> determining the array.</param>
		/// <param name="index"><see cref="Expression"/> determining the index whose value 
		/// should be obtained from the array.</param>
		/// <param name="kind">A kind of getter.</param>
		/// <remarks>Nothing is supposed on the evaluation stack. The value of the item is left
		/// on the evaluation stack.</remarks>
		public PhpTypeCode EmitGetItem(Expression/*!*/ array, Expression/*!*/ index, Operators.GetItemKinds kind)
		{
			ILEmitter il = codeGenerator.IL;
			
			// array:
			var arrayTypeCode = array.Emit(codeGenerator);

            // ensure the array is writeable is required
            if (EnsureWritable)
                codeGenerator.EmitEnsureWritable(arrayTypeCode);

			// index:
			PhpTypeCode index_type_code = codeGenerator.EmitArrayKey(this, index);

			// kind:
			if (kind == Operators.GetItemKinds.Get && QuietRead)
				kind = Operators.GetItemKinds.QuietGet;
			il.LdcI4((int)kind);

			// CALL Operators.GetItem(<array>, <index>, <kind>)
			codeGenerator.EmitGetItem(index_type_code, index, false);
			return PhpTypeCode.Object;
		}
开发者ID:dw4dev,项目名称:Phalanger,代码行数:32,代码来源:Chains.cs

示例11: EmitGetArrayItemRef

		public void EmitGetArrayItemRef(Expression/*!*/ array, Expression index)
		{
			array.Emit(codeGenerator);

			PhpTypeCode index_type_code = PhpTypeCode.Invalid;

			if (index != null)
				index_type_code = codeGenerator.EmitArrayKey(this, index);

			codeGenerator.EmitGetArrayItem(index_type_code, index, true);
		}
开发者ID:dw4dev,项目名称:Phalanger,代码行数:11,代码来源:Chains.cs

示例12: EmitConcatExpressionLoad

        /// <summary>
        /// Emits load of an argument of a concatenation.
        /// </summary>
        private static PhpTypeCode EmitConcatExpressionLoad(CodeGenerator/*!*/ codeGenerator, Expression/*!*/ expression)
        {
            // tries to evaluate the expression:
            if (expression.HasValue)
            {
                if (expression.Value is PhpBytes)
                {
                    codeGenerator.IL.LoadLiteral(expression.Value);
                    return PhpTypeCode.PhpBytes;
                }
                else
                {
                    // evaluated expression is converted to a string if necessary:
                    codeGenerator.IL.Emit(OpCodes.Ldstr, Convert.ObjectToString(expression.Value));
                    return PhpTypeCode.String;
                }
            }
            else
            {
                // emits non-evaluable expression:
                PhpTypeCode result = expression.Emit(codeGenerator);

                // the result should be converted to string: (so we know the type for the further analysis)
                if (result != PhpTypeCode.String && // string already
                    result != PhpTypeCode.Object && // object can contain PhpBytes, should be converted just when we know we need string
                    result != PhpTypeCode.PhpBytes  // keep PhpBytes
                    )
                {
                    codeGenerator.EmitBoxing(result);   // in case of value-type
                    codeGenerator.IL.Emit(OpCodes.Call, Methods.Convert.ObjectToString);
                    result = PhpTypeCode.String;
                }

                return result;
            }
        }
开发者ID:jdluzen,项目名称:Phalanger,代码行数:39,代码来源:ConcatEx.cs

示例13: 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

示例14: EmitMethodTargetExpr

        /// <summary>
        /// Emit the target of instance method invocation.
        /// </summary>
        /// <param name="cg"></param>
        /// <param name="targetExpr"></param>
        private static void EmitMethodTargetExpr(PHP.Core.CodeGenerator/*!*/cg, Expression/*!*/targetExpr)
        {
            // start a new operators chain (as the rest of chain is read)
            cg.ChainBuilder.Create();
            cg.ChainBuilder.Begin();
            cg.ChainBuilder.Lengthen(); // for hop over ->

            // prepare for operator invocation
            cg.EmitBoxing(targetExpr.Emit(cg));
            cg.ChainBuilder.End();
        }
开发者ID:Ashod,项目名称:Phalanger,代码行数:16,代码来源:CallSitesBuilder.cs

示例15: EmitEmptyArrayStrictEquality

        /// <summary>
        /// Emits strict equality to empty PHP array.
        /// </summary>
        /// <param name="codeGenerator">A code generator.</param>
        /// <param name="expr">Expression to be compared against.</param>
        private static void EmitEmptyArrayStrictEquality(CodeGenerator/*!*/codeGenerator, Expression/*!*/expr)
        {
            if (IsEmptyArrayEx(expr))
            {
                // array() === array()
                // LOAD true
                codeGenerator.IL.LoadBool(true);
            }
            else if (expr is Literal)
            {
                // array() === NULL|int|double|string|...
                // LOAD false
                codeGenerator.IL.LoadBool(false);
            }
            else
            {
                // array() === <expr>

                // LOAD <expr>
                var exprTypeCode = expr.Emit(codeGenerator);

                // check whether <expr> type can be an array
                switch (exprTypeCode)
                {
                    case PhpTypeCode.Boolean:
                    case PhpTypeCode.DObject:
                    case PhpTypeCode.Double:
                    case PhpTypeCode.Integer:
                    case PhpTypeCode.LongInteger:
                    case PhpTypeCode.PhpBytes:
                    case PhpTypeCode.PhpString:
                    case PhpTypeCode.String:
                        // always FALSE
                        codeGenerator.IL.Emit(OpCodes.Pop);
                        codeGenerator.IL.LoadBool(false);
                        break;
                    case PhpTypeCode.PhpArray:
                        // compare (PhpArray)<expr> with array()
                        codeGenerator.IL.Emit(OpCodes.Call, Methods.Operators.StrictEmptyPhpArrayEquality_PhpArray);
                        break;
                    default:
                        // compare <expr> with array()
                        codeGenerator.EmitBoxing(exprTypeCode);
                        codeGenerator.IL.Emit(OpCodes.Call, Methods.Operators.StrictEmptyPhpArrayEquality);
                        break;
                }                
            }
        }
开发者ID:proff,项目名称:Phalanger,代码行数:53,代码来源:BinaryEx.cs


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