Example #1
0
		/// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/>
		internal override PhpTypeCode Emit(CodeGenerator/*!*/ codeGenerator)
		{
			Statistics.AST.AddNode("IndirectVarUse");
			PhpTypeCode result = PhpTypeCode.Invalid;

			switch (codeGenerator.SelectAccess(access))
			{
				// This case occurs everytime we want to get current variable value
				// All we do is push the value onto the IL stack
				case AccessType.Read: // Push value onto a IL stack
					result = EmitNodeRead(codeGenerator);
					break;

				// This case occurs when the varible is written ($a = $b, then $a has Write mark)
				// We only prepare the stack for storing, the work will be done later,
				// by EmitAssign()
				case AccessType.Write:
					result = EmitNodeWrite(codeGenerator);
					break;

				case AccessType.None:
					EmitNodeRead(codeGenerator);
					codeGenerator.IL.Emit(OpCodes.Pop);
					result = PhpTypeCode.Void;
					break;

				case AccessType.ReadRef:
					// if the selector is set to the ReadRef, the chain is emitted as if it was written
					// (chained nodes are marked as ReadAndWrite):
					if (codeGenerator.AccessSelector == AccessType.ReadRef)
						codeGenerator.AccessSelector = AccessType.Write;

					result = EmitNodeReadRef(codeGenerator);
					Debug.Assert(result == PhpTypeCode.PhpReference);
					break;

				case AccessType.ReadUnknown:
					result = EmitNodeReadUnknown(codeGenerator);
					break;

				case AccessType.WriteRef:
					EmitNodeWriteRef(codeGenerator);
					result = PhpTypeCode.PhpReference;
					break;

				default:
					result = PhpTypeCode.Invalid;
					Debug.Fail();
					break;
			}
			return result;
		}
Example #2
0
		/// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/>
		internal override PhpTypeCode Emit(CodeGenerator/*!*/ codeGenerator)
		{
			Statistics.AST.AddNode("ItemUse");
			PhpTypeCode result = PhpTypeCode.Invalid;

			switch (codeGenerator.SelectAccess(access))
			{
				case AccessType.None:
					result = EmitNodeRead(codeGenerator, Operators.GetItemKinds.Get);
					codeGenerator.IL.Emit(OpCodes.Pop);
					break;

				case AccessType.Read:
					result = EmitNodeRead(codeGenerator, Operators.GetItemKinds.Get);
					break;

				case AccessType.Write:
					// prepares for write:
					result = EmitNodeWrite(codeGenerator);
					break;

				case AccessType.ReadRef:
					// if the selector is set to the ReadRef, the chain is emitted as if it was written
					// (chained nodes are marked as ReadAndWrite):
					if (codeGenerator.AccessSelector == AccessType.ReadRef)
						codeGenerator.AccessSelector = AccessType.Write;

					result = EmitNodeReadRef(codeGenerator);
					break;

				case AccessType.ReadUnknown:
					result = EmitNodeReadUnknown(codeGenerator);
					break;

				case AccessType.WriteRef:
					// prepares for write:					
					result = EmitNodeWriteRef(codeGenerator);
					break;

				default:
					Debug.Fail();
					break;
			}

			return result;
		}
Example #3
0
		/// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/>
		internal override PhpTypeCode Emit(CodeGenerator/*!*/ codeGenerator)
		{
			Statistics.AST.AddNode("FieldUse.Static");
			ChainBuilder chain = codeGenerator.ChainBuilder;
			PhpTypeCode result = PhpTypeCode.Invalid;

			switch (codeGenerator.SelectAccess(access))
			{
				case AccessType.Read:
					result = EmitRead(codeGenerator, false);
					if (chain.IsMember) chain.Lengthen();
					break;

				case AccessType.ReadUnknown:
					result = EmitRead(codeGenerator, true);
					if (chain.IsMember) chain.Lengthen();
					break;

				case AccessType.ReadRef:
					if (chain.IsMember)
					{
						chain.Lengthen();
						result = EmitRead(codeGenerator, false);
					}
					else
					{
						result = EmitRead(codeGenerator, true);
					}
					break;

				case AccessType.Write:
					if (chain.IsMember)
					{
						result = EmitEnsure(codeGenerator, chain);
						chain.Lengthen();
					}
					else
					{
						assignmentCallback = EmitWrite(codeGenerator, false);
						result = PhpTypeCode.Unknown;
					}
					break;

				case AccessType.WriteRef:
					if (chain.IsMember)
					{
						result = EmitEnsure(codeGenerator, chain);
						chain.Lengthen();
					}
					else
					{
						assignmentCallback = EmitWrite(codeGenerator, true);
						result = PhpTypeCode.Unknown;
					}
					break;

				case AccessType.None:
					result = PhpTypeCode.Void;
					break;
			}

			return result;
		}