/// <summary> /// If the exception can be handled in current scope, return true and /// set pc which is where the executive will jump to. Otherwise return /// false. /// </summary> /// <param name="pc">New pc value</param> /// <returns></returns> public bool CanHandleIt(ref int pc) { if (!IsStackUnwinding || TargetHandler == null || Context == null) { return(false); } // Note there is always an instance of ExceptionRegistration // associated with a scope -- either function defintion or a language // block -- and that instance of ExceptionRegistration associated // with current scope is called CurrentActiveRegistration which is // dynamically upated when switching scopes. if (TargetHandler.Registration == CurrentActiveRegistration) { CatchHandler catchHandler = TargetHandler.GetCatchHandler(Context.typeUID); if (catchHandler != null) { pc = catchHandler.Entry; return(true); } else { return(false); } } return(false); }
protected void EmitExceptionHandlingNode(ProtoCore.AST.Node node, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone) { #if ENABLE_EXCEPTION_HANDLING if (!IsParsingGlobal() && !IsParsingGlobalFunctionBody()) { return; } ExceptionHandlingNode exceptionNode = node as ExceptionHandlingNode; if (exceptionNode == null) return; tryLevel++; ExceptionHandler exceptionHandler = new ExceptionHandler(); exceptionHandler.TryLevel = tryLevel; ExceptionRegistration registration = core.ExceptionHandlingManager.Register(codeBlock.codeBlockId, globalProcIndex, globalClassIndex); registration.Add(exceptionHandler); exceptionHandler.StartPc = pc; TryBlockNode tryNode = exceptionNode.tryBlock; Debug.Assert(tryNode != null); foreach (var subnode in tryNode.body) { ProtoCore.Type inferedType = new ProtoCore.Type(); inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar; inferedType.IsIndexable = false; DfsTraverse(subnode, ref inferedType, false, graphNode, subPass); } exceptionHandler.EndPc = pc; // Jmp to code after catch block BackpatchTable backpatchTable = new BackpatchTable(); backpatchTable.Append(pc); EmitJmp(ProtoCore.DSASM.Constants.kInvalidIndex); foreach (var catchBlock in exceptionNode.catchBlocks) { CatchHandler catchHandler = new CatchHandler(); exceptionHandler.AddCatchHandler(catchHandler); CatchFilterNode filterNode = catchBlock.catchFilter; Debug.Assert(filterNode != null); catchHandler.FilterTypeUID = core.TypeSystem.GetType(filterNode.type.Name); if (catchHandler.FilterTypeUID == (int)PrimitiveType.kInvalidType) { string message = String.Format(ProtoCore.BuildData.WarningMessage.kExceptionTypeUndefined, filterNode.type.Name); buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kTypeUndefined, message, null, filterNode.line, filterNode.col); catchHandler.FilterTypeUID = (int)PrimitiveType.kTypeVar; } // For filter expression catch(e:int), generate an assignment // e = LX; catchHandler.Entry = pc; EmitInstrConsole(ProtoCore.DSASM.kw.push, ProtoCore.DSASM.kw.regLX); ProtoCore.DSASM.StackValue opLx = new ProtoCore.DSASM.StackValue(); opLx.optype = ProtoCore.DSASM.AddressType.Register; opLx.opdata = (int)ProtoCore.DSASM.Registers.LX; EmitPush(opLx); ProtoCore.DSASM.SymbolNode excpVarSymbol = null; bool stub; bool isAllocated = VerifyAllocation(filterNode.var.Value, globalClassIndex, globalProcIndex, out excpVarSymbol, out stub); int runtimeIndex = (!isAllocated) ? codeBlock.symbolTable.runtimeIndex : excpVarSymbol.runtimeTableIndex; if (!isAllocated) { excpVarSymbol = Allocate(filterNode.var.Value, globalProcIndex, new ProtoCore.Type()); } EmitPushVarData(runtimeIndex, 0, (int)PrimitiveType.kTypeVar, 0); EmitInstrConsole(ProtoCore.DSASM.kw.pop, filterNode.var.Value); EmitPopForSymbol(excpVarSymbol, filterNode.var.line, filterNode.var.col, filterNode.var.endLine, filterNode.var.endCol); ProtoCore.Type inferedType = new ProtoCore.Type(); inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar; inferedType.IsIndexable = false; foreach (var subnode in catchBlock.body) { inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar; inferedType.IsIndexable = false; DfsTraverse(subnode, ref inferedType, false, graphNode, subPass); } // Jmp to code after catch block backpatchTable.Append(pc); EmitJmp(ProtoCore.DSASM.Constants.kInvalidIndex); } Backpatch(backpatchTable.backpatchList, pc); tryLevel--; #endif }
protected void EmitExceptionHandlingNode(AssociativeNode node, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone) { #if ENABLE_EXCEPTION_HANDLING if (!IsParsingGlobal() && !IsParsingGlobalFunctionBody() && !IsParsingMemberFunctionBody()) { return; } tryLevel++; ExceptionHandlingNode exceptionNode = node as ExceptionHandlingNode; if (exceptionNode == null) return; ExceptionHandler exceptionHandler = new ExceptionHandler(); exceptionHandler.TryLevel = tryLevel; ExceptionRegistration registration = core.ExceptionHandlingManager.Register(codeBlock.codeBlockId, globalProcIndex, globalClassIndex); registration.Add(exceptionHandler); exceptionHandler.StartPc = pc; TryBlockNode tryNode = exceptionNode.tryBlock; Debug.Assert(tryNode != null); foreach (var subnode in tryNode.body) { ProtoCore.Type inferedType = new ProtoCore.Type(); inferedType.UID = (int) ProtoCore.PrimitiveType.kTypeVar; inferedType.IsIndexable = false; DfsTraverse(subnode, ref inferedType, false, graphNode, subPass); } exceptionHandler.EndPc = pc; // Jmp to code after catch block BackpatchTable backpatchTable = new BackpatchTable(); backpatchTable.Append(pc); EmitJmp(ProtoCore.DSASM.Constants.kInvalidIndex); foreach (var catchBlock in exceptionNode.catchBlocks) { CatchHandler catchHandler = new CatchHandler(); exceptionHandler.AddCatchHandler(catchHandler); CatchFilterNode filterNode = catchBlock.catchFilter; Debug.Assert(filterNode != null); catchHandler.FilterTypeUID = core.TypeSystem.GetType(filterNode.type.Name); if (catchHandler.FilterTypeUID == (int)PrimitiveType.kInvalidType) { string message = String.Format(ProtoCore.BuildData.WarningMessage.kExceptionTypeUndefined, filterNode.type.Name); buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kTypeUndefined, message, core.CurrentDSFileName, filterNode.line, filterNode.col); catchHandler.FilterTypeUID = (int)PrimitiveType.kTypeVar; } ProtoCore.Type inferedType = new ProtoCore.Type(); inferedType.UID = (int) ProtoCore.PrimitiveType.kTypeVar; inferedType.IsIndexable = false; DfsTraverse(filterNode.var, ref inferedType, false, graphNode, subPass); catchHandler.Entry = pc; foreach (var subnode in catchBlock.body) { inferedType.UID = (int) ProtoCore.PrimitiveType.kTypeVar; inferedType.IsIndexable = false; DfsTraverse(subnode, ref inferedType, false, graphNode, subPass); } // Jmp to code after catch block backpatchTable.Append(pc); EmitJmp(ProtoCore.DSASM.Constants.kInvalidIndex); } Backpatch(backpatchTable.backpatchList, pc); tryLevel--; #endif }
protected void EmitExceptionHandlingNode(ProtoCore.AST.Node node, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone) { if (!IsParsingGlobal() && !IsParsingGlobalFunctionBody()) { return; } ExceptionHandlingNode exceptionNode = node as ExceptionHandlingNode; if (exceptionNode == null) return; ExceptionRegistration registration = compileState.ExceptionHandlingManager.ExceptionTable.GetExceptionRegistration(codeBlock.codeBlockId, globalProcIndex, globalClassIndex); if (registration == null) { registration = compileState.ExceptionHandlingManager.ExceptionTable.Register(codeBlock.codeBlockId, globalProcIndex, globalClassIndex); Debug.Assert(registration != null); } tryLevel++; ExceptionHandler exceptionHandler = new ExceptionHandler(); exceptionHandler.TryLevel = tryLevel; registration.Add(exceptionHandler); TryBlockNode tryNode = exceptionNode.tryBlock; Debug.Assert(tryNode != null); foreach (var subnode in tryNode.body) { ProtoCore.Type inferedType = new ProtoCore.Type(); inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar; inferedType.IsIndexable = false; DfsTraverse(subnode, ref inferedType, false, graphNode, subPass); } // Jmp to code after catch block foreach (var catchBlock in exceptionNode.catchBlocks) { CatchHandler catchHandler = new CatchHandler(); exceptionHandler.AddCatchHandler(catchHandler); CatchFilterNode filterNode = catchBlock.catchFilter; Debug.Assert(filterNode != null); catchHandler.FilterTypeUID = compileState.TypeSystem.GetType(filterNode.type.Name); // For filter expression catch(e:int), generate an assignment // e = %tmpExp; BinaryExpressionNode exceptionAssignmentNode = new BinaryExpressionNode() { LeftNode = filterNode.var, Optr = ProtoCore.DSASM.Operator.assign, RightNode = new IdentifierNode() { Name = ProtoCore.DSASM.Constants.kTempExceptionVar, Value = ProtoCore.DSASM.Constants.kTempExceptionVar, datatype = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, false), } }; ProtoCore.Type inferedType = new ProtoCore.Type(); inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar; inferedType.IsIndexable = false; DfsTraverse(exceptionAssignmentNode, ref inferedType, false, graphNode, subPass); foreach (var subnode in catchBlock.body) { inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar; inferedType.IsIndexable = false; DfsTraverse(subnode, ref inferedType, false, graphNode, subPass); } // Jmp to code after catch block } tryLevel--; }
protected void EmitExceptionHandlingNode(AssociativeNode node, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone) { if (!IsParsingGlobal() && !IsParsingGlobalFunctionBody() && !IsParsingMemberFunctionBody()) return; tryLevel++; ExceptionHandlingNode exceptionNode = node as ExceptionHandlingNode; if (exceptionNode == null) return; ExceptionHandler exceptionHandler = new ExceptionHandler(); exceptionHandler.TryLevel = tryLevel; ExceptionRegistration registration = core.ExceptionHandlingManager.ExceptionTable.GetExceptionRegistration(codeBlock.codeBlockId, globalProcIndex, globalClassIndex); if (registration == null) { registration = core.ExceptionHandlingManager.ExceptionTable.Register(codeBlock.codeBlockId, globalProcIndex, globalClassIndex); Debug.Assert(registration != null); } registration.Add(exceptionHandler); TryBlockNode tryNode = exceptionNode.tryBlock; Debug.Assert(tryNode != null); foreach (var subnode in tryNode.body) { ProtoCore.Type inferedType = new ProtoCore.Type(); inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar; inferedType.IsIndexable = false; DfsTraverse(subnode, ref inferedType, false, graphNode, subPass); } foreach (var catchBlock in exceptionNode.catchBlocks) { CatchHandler catchHandler = new CatchHandler(); exceptionHandler.AddCatchHandler(catchHandler); CatchFilterNode filterNode = catchBlock.catchFilter; Debug.Assert(filterNode != null); catchHandler.FilterTypeUID = core.TypeSystem.GetType(filterNode.type.Name); ProtoCore.Type inferedType = new ProtoCore.Type(); inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar; inferedType.IsIndexable = false; DfsTraverse(filterNode.var, ref inferedType, false, graphNode, subPass); foreach (var subnode in catchBlock.body) { inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar; inferedType.IsIndexable = false; DfsTraverse(subnode, ref inferedType, false, graphNode, subPass); } // Jmp to code after catch block } tryLevel--; }
/// <summary> /// Add a catch handler /// </summary> /// <param name="catchHandler"></param> public void AddCatchHandler(CatchHandler catchHandler) { CatchHandlers.Add(catchHandler); catchHandler.Index = CatchHandlers.Count - 1; }
/// <summary> /// Add a catch handler /// </summary> /// <param name="catchHandler"></param> public void AddCatchHandler(CatchHandler catchHandler) { CatchHandlers.Add(catchHandler); catchHandler.Index = CatchHandlers.Count - 1; }