예제 #1
0
		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));
		}
예제 #2
0
        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;
            }

            throw new NotImplementedException();
        }
예제 #3
0
		/// <author>Tomas Matousek</author>
		/// <remarks>
		/// Emits the following code:
		/// <code>
		/// IPhpEnumerable enumerable = ARRAY as IPhpEnumerable;
		/// if (enumerable==null)
		/// {
		///   PhpException.InvalidForeachArgument();
		/// }
		/// else
		/// FOREACH_BEGIN:
		/// {
		///   IDictionaryEnumerator enumerator = enumerable.GetForeachEnumerator(KEYED,ALIASED,TYPE_HANDLE);
		///    
		///   goto LOOP_TEST;
		///   LOOP_BEGIN:
		///   {
		///     ASSIGN(value,enumerator.Value);
		///     ASSIGN(key,enumerator.Key);
		///     
		///     BODY; 
		///   }
		///   LOOP_TEST:
		///   if (enumerator.MoveNext()) goto LOOP_BEGIN;
		/// } 
		/// FOREACH_END:
		/// </code>
		/// </remarks>
		/// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/>
		internal override void Emit(CodeGenerator codeGenerator)
		{
			Statistics.AST.AddNode("Loop.Foreach");
			ILEmitter il = codeGenerator.IL;

			Label foreach_end = il.DefineLabel();
			Label foreach_begin = il.DefineLabel();
			Label loop_begin = il.DefineLabel();
			Label loop_test = il.DefineLabel();

			codeGenerator.BranchingStack.BeginLoop(loop_test, foreach_end,
			  codeGenerator.ExceptionBlockNestingLevel);

			LocalBuilder enumerable = il.GetTemporaryLocal(typeof(IPhpEnumerable));

			// marks foreach "header" (the first part of the IL code):
			codeGenerator.MarkSequencePoint(
			  enumeree.Position.FirstLine,
			  enumeree.Position.FirstColumn,
			  valueVariable.Position.LastLine,
			  valueVariable.Position.LastColumn + 1);

			// enumerable = array as IPhpEnumerable;
			enumeree.Emit(codeGenerator);
			il.Emit(OpCodes.Isinst, typeof(IPhpEnumerable));
			il.Stloc(enumerable);

			// if (enumerable==null)
			il.Ldloc(enumerable);
			il.Emit(OpCodes.Brtrue, foreach_begin);
			{
				// CALL PhpException.InvalidForeachArgument();
				codeGenerator.EmitPhpException(Methods.PhpException.InvalidForeachArgument);
				il.Emit(OpCodes.Br, foreach_end);
			}
			// FOREACH_BEGIN:
			il.MarkLabel(foreach_begin);
			{
				LocalBuilder enumerator = il.GetTemporaryLocal(typeof(System.Collections.IDictionaryEnumerator));

				// enumerator = enumerable.GetForeachEnumerator(KEYED,ALIASED,TYPE_HANDLE);
				il.Ldloc(enumerable);
				il.LoadBool(keyVariable != null);
				il.LoadBool(valueVariable.Alias);
				codeGenerator.EmitLoadClassContext();
				il.Emit(OpCodes.Callvirt, Methods.IPhpEnumerable_GetForeachEnumerator);
				il.Stloc(enumerator);

				// goto LOOP_TEST;
				il.Emit(OpCodes.Br, loop_test);

				// LOOP_BEGIN:
				il.MarkLabel(loop_begin);
				{
					// enumerator should do dereferencing and deep copying (if applicable):
					// ASSIGN(value,enumerator.Value);
					valueVariable.Emit(codeGenerator);
					il.Ldloc(enumerator);
					il.Emit(OpCodes.Callvirt, Properties.IDictionaryEnumerator_Value.GetGetMethod());
					if (valueVariable.Alias) il.Emit(OpCodes.Castclass, typeof(PhpReference));
					valueVariable.EmitAssign(codeGenerator);

					if (keyVariable != null)
					{
						// enumerator should do dereferencing and deep copying (if applicable):
						// ASSIGN(key,enumerator.Key);
						keyVariable.Emit(codeGenerator);
						il.Ldloc(enumerator);
						il.Emit(OpCodes.Callvirt, Properties.IDictionaryEnumerator_Key.GetGetMethod());
						keyVariable.EmitAssign(codeGenerator);
					}

					// BODY:
					body.Emit(codeGenerator);
				}
				// LOOP_TEST:
				il.MarkLabel(loop_test);

				// marks foreach "header" (the second part of the code):
				codeGenerator.MarkSequencePoint(
				  enumeree.Position.FirstLine,
				  enumeree.Position.FirstColumn,
				  valueVariable.Position.LastLine,
				  valueVariable.Position.LastColumn + 1);

				// if (enumerator.MoveNext()) goto LOOP_BEGIN;
				il.Ldloc(enumerator);
				il.Emit(OpCodes.Callvirt, Methods.IEnumerator_MoveNext);
				il.Emit(OpCodes.Brtrue, loop_begin);

                //
                il.ReturnTemporaryLocal(enumerator);
			}
			// FOREACH_END:
			il.MarkLabel(foreach_end);

            il.ReturnTemporaryLocal(enumerable);

			codeGenerator.BranchingStack.EndLoop();

			il.ForgetLabel(foreach_end);
			il.ForgetLabel(foreach_begin);
			il.ForgetLabel(loop_begin);
			il.ForgetLabel(loop_test);
		}