コード例 #1
0
        public ItemUse(Text.Span p, VarLikeConstructUse /*!*/ array, Expression index, bool functionArrayDereferencing = false)
            : base(p)
        {
            Debug.Assert(array != null);

            this.array = array;
            this.index = index;
            this.functionArrayDereferencing = functionArrayDereferencing;
        }
コード例 #2
0
ファイル: ItemUse.cs プロジェクト: Ashod/Phalanger
        public ItemUse(Position p, VarLikeConstructUse/*!*/ array, Expression index, bool functionArrayDereferencing = false)
			: base(p)
		{
			Debug.Assert(array != null);

			this.array = array;
			this.index = index;
            this.functionArrayDereferencing = functionArrayDereferencing;
		}
コード例 #3
0
 virtual public void VisitVarLikeConstructUse(VarLikeConstructUse x)
 {
     VisitElement(x.IsMemberOf);
 }
コード例 #4
0
ファイル: Chains.cs プロジェクト: dw4dev/Phalanger
		/// <summary>
		/// Emits IL instructions that ensure that the specified property of an object is
		/// of the <see cref="PhpArray"/> type.
		/// </summary>
		/// <param name="varObject">Represents the instance whose property should be examined.</param>
		/// <param name="fieldName">A <see cref="SimpleVarUse"/> that evaluates to the property name.</param>
		/// <param name="ensureArray">Whether to ensure that static property is an array (or an object).</param>
		/// <remarks>Nothing is expected on the evaluation stack. If the property is of <see cref="PhpArray"/> type
		/// it is left on the evaluation stack. Otherwise the control is transfered to the end of chain.</remarks>
		public PhpTypeCode EmitEnsureProperty(VarLikeConstructUse/*!*/ varObject, SimpleVarUse/*!*/ fieldName, bool ensureArray)
		{
			// Template: PhpArray EnsurePropertyIsArray(DObject,field,DTypeDesc)
			Debug.Assert(varObject != null && fieldName != null);
			Debug.Assert(fieldName is DirectVarUse || fieldName is IndirectVarUse);

			LocationTypes location;
			DProperty property = ResolveProperty(varObject, fieldName, out location);

			ILEmitter il = codeGenerator.IL;

			PhpField php_field = property as PhpField;
			if (php_field != null) // we can emit code that manipulates the property directly
			{
				// HACK HACK
				EmitEnsurePhpFieldDirect(php_field, fieldName, ensureArray);
			}
			else
			{
				switch (location)
				{
					case LocationTypes.GlobalCode:
						{
							// call EnsurePropertyIsArray
							codeGenerator.EmitLoadSelf();
							fieldName.EmitName(codeGenerator);
							codeGenerator.EmitLoadClassContext();

							if (ensureArray)
							{
								il.Emit(OpCodes.Call, Methods.Operators.EnsurePropertyIsArray);
							}
							else
							{
								codeGenerator.EmitLoadScriptContext();
								il.Emit(OpCodes.Call, Methods.Operators.EnsurePropertyIsObject);
							}
							break;
						}

					case LocationTypes.MethodDecl:
						{
							if (ensureArray) this.Lengthen(); // for hop over ->
							FunctionCall func = varObject as FunctionCall;
							if (func == null)
							{
								varObject.Emit(codeGenerator);
							}
							else
							{
								this.LoadAddressOfFunctionReturnValue = true;
								func.Emit(codeGenerator);
								RecastValueReturnedByFunctionCall();
							}
							fieldName.EmitName(codeGenerator);
							codeGenerator.EmitLoadClassContext();

							if (ensureArray)
							{
								il.Emit(OpCodes.Call, Methods.Operators.EnsurePropertyIsArray);
							}
							else
							{
								codeGenerator.EmitLoadScriptContext();
								il.Emit(OpCodes.Call, Methods.Operators.EnsurePropertyIsObject);
							}
							EmitErrorCheck(ensureArray);
							break;
						}

					// if the location was FunctionDecl, appropriate code was already generated by GetDProperty
				}
			}
			return (ensureArray ? PhpTypeCode.PhpArray : PhpTypeCode.DObject);
		}
コード例 #5
0
ファイル: Chains.cs プロジェクト: dw4dev/Phalanger
			/// <summary>
			/// Gets the <see cref="ObjectFieldLazyEmitInfo"/> object stored in collection.
			/// </summary>
			/// <param name="var_object"></param>
			/// <param name="old_IsArrayItem"></param>
			/// <param name="old_IsLastMember"></param>
			/// <returns></returns>
			/// <remarks>
			/// This method should only be called from <see cref="ChainBuilder.GetObjectForLazyEmit"/> method.
			/// </remarks>
			public ObjectFieldLazyEmitInfo GetItem(VarLikeConstructUse var_object, bool old_IsArrayItem, bool old_IsLastMember)
			{
				if (stack.Count != 0)
				{
					ObjectFieldLazyEmitInfo info = (ObjectFieldLazyEmitInfo)stack.Pop();
					Debug.Assert(info != null);
					info.ObjectForLazyEmit = var_object;
					info.Old_IsArrayItem = old_IsArrayItem;
					info.Old_IsLastMember = old_IsLastMember;
				}
				return new ObjectFieldLazyEmitInfo(var_object, old_IsArrayItem, old_IsLastMember);
			}
コード例 #6
0
ファイル: Chains.cs プロジェクト: dw4dev/Phalanger
			public void Reset()
			{
				objectForLazyEmit = null;
			}
コード例 #7
0
ファイル: Chains.cs プロジェクト: dw4dev/Phalanger
			public ObjectFieldLazyEmitInfo(VarLikeConstructUse var_object, bool old_IsArrayItem, bool old_IsLastMember)
			{
				this.objectForLazyEmit = var_object;
				this.Old_IsArrayItem = old_IsArrayItem;
				this.Old_IsLastMember = old_IsLastMember;
			}
コード例 #8
0
ファイル: Chains.cs プロジェクト: dw4dev/Phalanger
		/// <summary>
		/// Tries to find an instance of <see cref="DProperty"/> that corresponds to an instance property given by
		/// <paramref name="varObject"/> and <paramref name="fieldName"/>. Currently it is possible only if
		/// <paramref name="varObject"/> represents <B>$this</B> and <paramref name="fieldName"/> is a compile time
		/// known instance property, which is surely accessible from current location.
		/// </summary>
		/// <param name="varObject">Represents the left side of <B>-&gt;</B>.</param>
		/// <param name="fieldName">Represents the right side of <B>-&gt;</B>.</param>
		/// <param name="location">Current location, valid only if the return value is <B>null</B>. Used by the caller to
		/// decide what kind of run time access should be emitted.</param>
		/// <returns>A valid non-<B>null</B> <see cref="PhpField"/> if the field was found, <B>null</B> otherwise.</returns>
		internal DProperty ResolveProperty(VarLikeConstructUse varObject, SimpleVarUse fieldName, out LocationTypes location)
		{
			DirectVarUse direct_var = varObject as DirectVarUse;
			DirectVarUse direct_field_name;

			if (direct_var != null && (direct_field_name = fieldName as DirectVarUse) != null &&
				direct_var.IsMemberOf == null && direct_var.VarName.IsThisVariableName)
			{
				ILEmitter il = codeGenerator.IL;
				location = codeGenerator.LocationStack.LocationType;
				switch (location)
				{
					case LocationTypes.GlobalCode:
						{
							// load $this from one of Main's arguments and check for null
							Label this_non_null = il.DefineLabel();

							codeGenerator.EmitLoadSelf();
							il.Emit(OpCodes.Brtrue_S, this_non_null);
							codeGenerator.EmitPhpException(Methods.PhpException.ThisUsedOutOfObjectContext);
							il.Emit(OpCodes.Br, TopChain.ErrorLabel);
							il.MarkLabel(this_non_null, true);

							return null;
						}

					case LocationTypes.FunctionDecl:
						{
							// always throws error
							codeGenerator.EmitPhpException(Methods.PhpException.ThisUsedOutOfObjectContext);
							il.Emit(OpCodes.Br, TopChain.ErrorLabel);

							return null;
						}

					case LocationTypes.MethodDecl:
						{
							CompilerLocationStack.MethodDeclContext context = codeGenerator.LocationStack.PeekMethodDecl();
							if (context.Method.IsStatic)
							{
								// always throws error
								codeGenerator.EmitPhpException(Methods.PhpException.ThisUsedOutOfObjectContext);
								il.Emit(OpCodes.Br, TopChain.ErrorLabel);

								location = LocationTypes.FunctionDecl;
								return null;
							}
							else
							{
								DProperty property;
								if (context.Type.GetProperty(direct_field_name.VarName, context.Type, out property)
									== GetMemberResult.OK && !property.IsStatic)
								{
									return property;
								}
							}
							break;
						}
				}
			}

			location = LocationTypes.MethodDecl;
			return null;
		}
コード例 #9
0
ファイル: TreeVisitor.cs プロジェクト: dw4dev/Phalanger
 virtual public void VisitVarLikeConstructUse(VarLikeConstructUse x)
 {
     VisitElement(x.IsMemberOf);
 }