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(); }
public virtual void VisitCFGCatchBlock(CatchBlock x) { Accept(x.Variable); VisitCFGBlockInternal(x); }
public virtual void VisitCFGCatchBlock(CatchBlock x) { VisitTypeRef(x.TypeRef); Accept(x.Variable); VisitCFGBlockInternal(x); }
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(); }
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(); }
public sealed override object VisitCFGCatchBlock(CatchBlock x) => Repair(x);
public virtual CatchBlock OnVisitCFGCatchBlock(CatchBlock x) => (CatchBlock)base.VisitCFGCatchBlock(x);
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(); }
public virtual TResult VisitCFGCatchBlock(CatchBlock x) => DefaultVisitBlock(x);