Beispiel #1
0
        void EmitCatchBlock(CodeGenerator cg, CatchBlock catchBlock)
        {
            Debug.Assert(catchBlock.Variable.Variable != null);

            if (catchBlock.TypeRef.ResolvedType.IsErrorTypeOrNull())
            {
                Debug.WriteLine("Handle unknown exception types dynamically."); // TODO: if (ex is ctx.ResolveType(ExceptionTypeName)) { ... }
                return;
            }

            var extype = catchBlock.TypeRef.ResolvedType;

            cg.Builder.AdjustStack(1); // Account for exception on the stack.

            cg.Builder.OpenLocalScope(ScopeType.Catch, (Microsoft.Cci.ITypeReference)extype);

            // <tmp> = <ex>
            var tmploc = cg.GetTemporaryLocal(extype);

            cg.Builder.EmitLocalStore(tmploc);

            var varplace = catchBlock.Variable.BindPlace(cg);

            Debug.Assert(varplace != null);

            // $x = <tmp>
            varplace.EmitStorePrepare(cg);
            cg.Builder.EmitLocalLoad(tmploc);
            varplace.EmitStore(cg, (TypeSymbol)tmploc.Type);

            //
            cg.ReturnTemporaryLocal(tmploc);
            tmploc = null;

            //
            cg.GenerateScope(catchBlock, NextBlock.Ordinal);

            //
            cg.Builder.CloseLocalScope();
        }
Beispiel #2
0
 public virtual void VisitCFGCatchBlock(CatchBlock x)
 {
     Accept(x.Variable);
     VisitCFGBlockInternal(x);
 }
Beispiel #3
0
 public virtual void VisitCFGCatchBlock(CatchBlock x)
 {
     VisitTypeRef(x.TypeRef);
     Accept(x.Variable);
     VisitCFGBlockInternal(x);
 }
Beispiel #4
0
        void EmitCatchBlock(CodeGenerator cg, CatchBlock catchBlock)
        {
            Debug.Assert(catchBlock.Variable.Variable != null);

            var        il = cg.Builder;
            TypeSymbol extype;

            il.AdjustStack(1);                                             // Account for exception on the stack.

            var trefs = BoundMultipleTypeRef.Flattern(catchBlock.TypeRef); // set of types we catch in this catch block

            // do we have to generate .filter or just .catch<type>:
            if (trefs.Length != 1 || trefs[0].ResolvedType.IsErrorTypeOrNull() || !trefs[0].ResolvedType.IsOfType(cg.CoreTypes.Exception))
            {
                // Template: catch when
                il.OpenLocalScope(ScopeType.Filter);

                // STACK : object

                if (trefs.Length == 1)
                {
                    EmitTypeCheck(cg, trefs[0]);

                    extype = trefs[0].ResolvedType.IsErrorTypeOrNull()
                        ? cg.CoreTypes.Object.Symbol
                        : trefs[0].ResolvedType;
                }
                else
                {
                    EmitMultipleTypeCheck(cg, trefs);

                    extype = cg.CoreTypes.Object.Symbol;
                }

                // STACK : i4 ? handle : continue

                il.MarkFilterConditionEnd();

                // STACK : object
                cg.EmitCastClass(cg.CoreTypes.Exception);   // has to be casted to System.Exception in order to generate valid IL
                cg.EmitCastClass(extype);
            }
            else
            {
                // Template: catch (TypeRef)
                extype = trefs[0].ResolvedType;
                il.OpenLocalScope(ScopeType.Catch, cg.Module.Translate(extype, null, cg.Diagnostics));
            }

            // STACK : extype

            // <tmp> = <ex>
            cg.EmitSequencePoint(catchBlock.Variable.PhpSyntax);
            var tmploc = cg.GetTemporaryLocal(extype);

            il.EmitLocalStore(tmploc);

            var varplace = catchBlock.Variable.BindPlace(cg);

            Debug.Assert(varplace != null);

            // $x = <tmp>
            varplace.EmitStorePrepare(cg);
            il.EmitLocalLoad(tmploc);
            varplace.EmitStore(cg, (TypeSymbol)tmploc.Type);

            //
            cg.ReturnTemporaryLocal(tmploc);
            tmploc = null;

            //
            cg.GenerateScope(catchBlock, NextBlock.Ordinal);

            //
            il.CloseLocalScope();
        }
Beispiel #5
0
        void EmitCatchBlock(CodeGenerator cg, CatchBlock catchBlock)
        {
            Debug.Assert(catchBlock.Variable == null || catchBlock.Variable.Variable != null);

            var        il = cg.Builder;
            TypeSymbol extype;

            il.AdjustStack(1); // Account for exception on the stack.

            // set of types we catch in this catch block
            var trefs = catchBlock.TypeRef is TypeRef.BoundMultipleTypeRef mt
                ? mt.TypeRefs
                : ImmutableArray.Create((BoundTypeRef)catchBlock.TypeRef);

            // do we have to generate .filter or just .catch<type>:
            if (trefs.Length != 1 || trefs[0].ResolvedType.IsErrorTypeOrNull() || !trefs[0].ResolvedType.IsOfType(cg.CoreTypes.Exception))
            {
                // Template: catch when
                il.OpenLocalScope(ScopeType.Filter);

                // STACK : object

                if (trefs.Length == 1)
                {
                    EmitTypeCheck(cg, trefs[0]);

                    extype = trefs[0].ResolvedType.IsErrorTypeOrNull()
                        ? cg.CoreTypes.Object.Symbol
                        : trefs[0].ResolvedType;
                }
                else
                {
                    EmitMultipleTypeCheck(cg, trefs);

                    extype = cg.CoreTypes.Object.Symbol;
                }

                // STACK : i4 ? handle : continue

                il.MarkFilterConditionEnd();

                // STACK : object
                cg.EmitCastClass(cg.CoreTypes.Exception);   // has to be casted to System.Exception in order to generate valid IL
                cg.EmitCastClass(extype);
            }
            else
            {
                // Template: catch (TypeRef)
                extype = trefs[0].ResolvedType;
                il.OpenLocalScope(ScopeType.Catch, cg.Module.Translate(extype, null, cg.Diagnostics));
            }

            // STACK : extype
            if (catchBlock.Variable != null)
            {
                cg.EmitSequencePoint(catchBlock.Variable.PhpSyntax);

                // <tmp> = <ex>
                var tmploc = cg.GetTemporaryLocal(extype);
                il.EmitLocalStore(tmploc);

                // $x = <tmp>
                var varplace = catchBlock.Variable.BindPlace(cg);
                varplace.EmitStore(cg, tmploc, catchBlock.Variable.TargetAccess());
                cg.ReturnTemporaryLocal(tmploc);
            }
            else
            {
                il.EmitOpCode(ILOpCode.Pop);
            }

            //
            if (EmitCatchFinallyOutsideScope)
            {
                // .br
                il.EmitBranch(ILOpCode.Br, catchBlock);
            }
            else
            {
                // { .. }
                cg.GenerateScope(catchBlock, NextBlock.Ordinal);
            }

            //
            il.CloseLocalScope();
        }
Beispiel #6
0
 public sealed override object VisitCFGCatchBlock(CatchBlock x) => Repair(x);
Beispiel #7
0
 public virtual CatchBlock OnVisitCFGCatchBlock(CatchBlock x) => (CatchBlock)base.VisitCFGCatchBlock(x);
Beispiel #8
0
        void EmitCatchBlock(CodeGenerator cg, CatchBlock catchBlock)
        {
            Debug.Assert(catchBlock.Variable.Variable != null);

            var        il = cg.Builder;
            TypeSymbol extype;

            il.AdjustStack(1); // Account for exception on the stack.

            if (catchBlock.TypeRef.ResolvedType.IsErrorTypeOrNull() || !catchBlock.TypeRef.ResolvedType.IsOfType(cg.CoreTypes.Exception))
            {
                // Template: catch when
                il.OpenLocalScope(ScopeType.Filter);

                // STACK : object

                if (catchBlock.TypeRef.ResolvedType.IsErrorTypeOrNull())
                {
                    extype = cg.CoreTypes.Object.Symbol;

                    // Template: filter(Operators.IsInstanceOf(<stack>, type))
                    catchBlock.TypeRef.EmitLoadTypeInfo(cg, false);
                    cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.IsInstanceOf_Object_PhpTypeInfo)
                    .Expect(SpecialType.System_Boolean);
                }
                else
                {
                    extype = catchBlock.TypeRef.ResolvedType;

                    // Template: filter (<stack> is Interface)
                    il.EmitOpCode(ILOpCode.Isinst);
                    cg.EmitSymbolToken(extype, null);
                    il.EmitNullConstant();
                    il.EmitOpCode(ILOpCode.Cgt_un); // value > null : bool
                }

                // STACK : i4 ? handle : continue

                il.MarkFilterConditionEnd();

                // STACK : object
                cg.EmitCastClass(cg.CoreTypes.Exception);   // has to be casted to System.Exception in order to generate valid IL
                cg.EmitCastClass(extype);
            }
            else
            {
                // Template: catch (TypeRef)
                extype = catchBlock.TypeRef.ResolvedType;
                il.OpenLocalScope(ScopeType.Catch, cg.Module.Translate(extype, null, cg.Diagnostics));
            }

            // STACK : extype

            // <tmp> = <ex>
            cg.EmitSequencePoint(catchBlock.Variable.PhpSyntax);
            var tmploc = cg.GetTemporaryLocal(extype);

            il.EmitLocalStore(tmploc);

            var varplace = catchBlock.Variable.BindPlace(cg);

            Debug.Assert(varplace != null);

            // $x = <tmp>
            varplace.EmitStorePrepare(cg);
            il.EmitLocalLoad(tmploc);
            varplace.EmitStore(cg, (TypeSymbol)tmploc.Type);

            //
            cg.ReturnTemporaryLocal(tmploc);
            tmploc = null;

            //
            cg.GenerateScope(catchBlock, NextBlock.Ordinal);

            //
            il.CloseLocalScope();
        }
Beispiel #9
0
 public virtual TResult VisitCFGCatchBlock(CatchBlock x) => DefaultVisitBlock(x);