Example #1
0
        /// <summary>
        /// Emits the catch-block.
        /// </summary>
        /// <param name="codeGenerator">A code generator.</param>
        /// <param name="exceptionLocal">A local variable containing an instance of <see cref="Library.SPL.Exception"/>.</param>
        /// <param name="endLabel">A label in IL stream where the processing of the try-catch blocks ends.</param>
        /// <param name="nextCatchLabel">A label in IL stream where the next catch block processing begins.</param>
        internal void Emit(CodeGenerator /*!*/ codeGenerator, LocalBuilder /*!*/ exceptionLocal, Label endLabel,
                           Label nextCatchLabel)
        {
            ILEmitter il = codeGenerator.IL;

            codeGenerator.MarkSequencePoint(
                variable.Position.FirstLine,
                variable.Position.FirstColumn,
                variable.Position.LastLine,
                variable.Position.LastColumn + 1
                );

            // IF !InstanceOf(<class name>) GOTO next_catch;
            il.Ldloc(exceptionLocal);
            resolvedType.EmitInstanceOf(codeGenerator, null);
            il.Emit(OpCodes.Brfalse, nextCatchLabel);

            // variable = exception;
            variable.Emit(codeGenerator);
            il.Ldloc(exceptionLocal);
            variable.EmitAssign(codeGenerator);

            foreach (Statement statement in statements)
            {
                statement.Emit(codeGenerator);
            }

            // LEAVE end;
            il.Emit(OpCodes.Leave, endLabel);
        }
Example #2
0
        /// <summary>
        /// Emits type hint test on the argument if specified.
        /// </summary>
        internal void EmitTypeHintTest(CodeGenerator /*!*/ codeGenerator)
        {
            int real_index = routine.FirstPhpParameterIndex + index;

            // not type hint specified:
            if (typeHint == null)
            {
                return;
            }

            Debug.Assert(resolvedTypeHint != null);

            ILEmitter il          = codeGenerator.IL;
            Label     endif_label = il.DefineLabel();

            // IF (DEREF(ARG[argIdx]) is not of hint type) THEN
            il.Ldarg(real_index);
            if (PassedByRef)
            {
                il.Emit(OpCodes.Ldfld, Fields.PhpReference_Value);
            }

            resolvedTypeHint.EmitInstanceOf(codeGenerator, null);
            il.Emit(OpCodes.Brtrue, endif_label);

            // add a branch allowing null values if the argument is optional with null default value (since PHP 5.1.0);
            if (initValue != null && initValue.HasValue && initValue.Value == null)
            {
                // IF (DEREF(ARG[argIdx]) != null) THEN
                il.Ldarg(real_index);
                if (PassedByRef)
                {
                    il.Emit(OpCodes.Ldfld, Fields.PhpReference_Value);
                }
                il.Emit(OpCodes.Brfalse, endif_label);
            }

            // CALL PhpException.InvalidArgumentType(<param_name>, <class_name>);
            il.Emit(OpCodes.Ldstr, name.ToString());
            il.Emit(OpCodes.Ldstr, resolvedTypeHint.FullName);
            codeGenerator.EmitPhpException(Methods.PhpException.InvalidArgumentType);

            // END IF;
            // END IF;
            il.MarkLabel(endif_label);
        }
Example #3
0
            /// <summary>
            /// Emits the catch-block.
            /// </summary>
            /// <param name="node">Instance.</param>
            /// <param name="codeGenerator">A code generator.</param>
            /// <param name="exceptionLocal">A local variable containing an instance of <see cref="Library.SPL.Exception"/>.</param>
            /// <param name="endLabel">A label in IL stream where the processing of the try-catch blocks ends.</param>
            /// <param name="nextCatchLabel">A label in IL stream where the next catch block processing begins.</param>
            public void Emit(CatchItem /*!*/ node, CodeGenerator /*!*/ codeGenerator,
                             LocalBuilder /*!*/ exceptionLocal,
                             Label endLabel, Label nextCatchLabel)
            {
                ILEmitter il = codeGenerator.IL;

                codeGenerator.MarkSequencePoint(node.Variable);

                // IF !InstanceOf(<class name>) GOTO next_catch;
                il.Ldloc(exceptionLocal);
                resolvedType.EmitInstanceOf(codeGenerator, null);
                il.Emit(OpCodes.Brfalse, nextCatchLabel);

                // variable = exception;
                node.Variable.Emit(codeGenerator);
                il.Ldloc(exceptionLocal);
                SimpleVarUseHelper.EmitAssign(node.Variable, codeGenerator);

                node.Statements.Emit(codeGenerator);

                // LEAVE end;
                il.Emit(OpCodes.Leave, endLabel);
            }