/// <summary> /// Walk through chained exception registration instances to find out /// the corresponding exception handler. Returns null if cannot find /// the handler. /// </summary> /// <param name="context">Exception context</param> /// <returns></returns> public ExceptionHandler FindExceptionHandler(ExceptionContext context) { int regIndex = IndexOf(context.codeBlockId, context.functionScope, context.classScope); Validity.Assert(regIndex != ProtoCore.DSASM.Constants.kInvalidIndex); ExceptionRegistration registration = Registrations[regIndex]; int pc = context.pc; while (true) { int handlerIndex; if (registration.HandleIt(pc, context.typeUID, out handlerIndex)) { Validity.Assert(handlerIndex != ProtoCore.DSASM.Constants.kInvalidIndex); return(registration.Handlers[handlerIndex]); } else { int parentIndex = registration.ParentIndex; if (parentIndex == ProtoCore.DSASM.Constants.kInvalidIndex) { break; } else { pc = registration.LastPc; registration = Registrations[parentIndex]; } } } return(null); }
public ExceptionRegistration Register(int blockId, int procIndex, int classIndex) { ExceptionRegistration registration = ExceptionTable.GetExceptionRegistration(blockId, procIndex, classIndex); if (registration == null) { registration = this.ExceptionTable.Register(blockId, procIndex, classIndex); Validity.Assert(registration != null); } return(registration); }
/// <summary> /// To switch scope, so need to set current active exception registration /// for current scope. Each exception registration instance is identified /// by three parameter: block id, function index and class index. PC is /// needed so that the executive knows where the switch of context happens, /// PC values will be used to determine which excpetion handler will handle /// this exception. /// </summary> /// <param name="blockId">Block ID</param> /// <param name="functionIdex">Fucntion index</param> /// <param name="classIndex">Class index</param> /// <param name="pc">PC</param> public void SwitchContextTo(int blockId, int functionIdex, int classIndex, int pc) { int parentIndex = CurrentActiveRegistration.RegistrationTableIndex; ExceptionRegistration reg = ExceptionTable.GetExceptionRegistration(blockId, functionIdex, classIndex); if (reg != null) { reg.ParentIndex = parentIndex; CurrentActiveRegistration = reg; CurrentActiveRegistration.LastPc = pc; } }
/// <summary> /// Register an ExceptionRegistration instance for a scope. It is identified /// by three parameters: code block id, function index and class index. /// </summary> /// <param name="codeBlockId"></param> /// <param name="functionScope"></param> /// <param name="classScope"></param> /// <returns></returns> public ExceptionRegistration Register(int codeBlockId, int functionScope, int classScope) { int index = IndexOf(codeBlockId, functionScope, classScope); if (index != ProtoCore.DSASM.Constants.kInvalidIndex) { return(Registrations[index]); } ExceptionRegistration registration = new ExceptionRegistration(codeBlockId, functionScope, classScope); Registrations.Add(registration); registration.RegistrationTableIndex = Registrations.Count - 1; // reg.ParentIndex will be set at run-time because at this moment // we have no idea about its calling context return(registration); }
public ExceptionHandlingManager() { ExceptionTable = new ExceptionRegistrationTable(); int invalidIndex = ProtoCore.DSASM.Constants.kInvalidIndex; // System default exception registration SystemRegistration = ExceptionTable.Register(invalidIndex, invalidIndex, invalidIndex); SystemRegistration.ParentIndex = ProtoCore.DSASM.Constants.kInvalidIndex; // Exception registration for the top most associative code block. // // Why we need to manually add this one even when code gen is compiling // the top-most language node the exception registration for that // language code block will be added? // // The reason is ParentIndex, which will be updated dynamcailly at // run-time, i.e., it should point to the index of exception registration // for the upper scope. Normally, we will set this value either at // OpCode.Bounce or at OpCode.CallR. But for the top-most language // block, it doesnt start from there, so here we manully set its // ParentIndex to the default system exception registration instance. // // If we can consolidate the updating code at OpCode.Bounce and at // OpCode.CallR, then it is not necessary to manually add this one. // (The reason that we have to do that is because we need the value // of pc in the upper scope, i.e., where does the execution jump to // other function call or language block; otherwise Execute() is a // ideal place to put that updating code). Should refactor this piece // of code for that case. -- Yu Ke TopMostAssocBlockRegistration = ExceptionTable.Register(0, invalidIndex, invalidIndex); TopMostAssocBlockRegistration.ParentIndex = SystemRegistration.RegistrationTableIndex; CurrentActiveRegistration = TopMostAssocBlockRegistration; IsStackUnwinding = false; TargetHandler = null; Context = null; Observers = new List <IFirstHandExceptionObserver>(); }
public ExceptionHandlingManager() { ExceptionTable = new ExceptionRegistrationTable(); int invalidIndex = ProtoCore.DSASM.Constants.kInvalidIndex; // System default exception registration SystemRegistration = ExceptionTable.Register(invalidIndex, invalidIndex, invalidIndex); SystemRegistration.ParentIndex = ProtoCore.DSASM.Constants.kInvalidIndex; // Exception registration for the top most associative code block. // // Why we need to manually add this one even when code gen is compiling // the top-most language node the exception registration for that // language code block will be added? // // The reason is ParentIndex, which will be updated dynamcailly at // run-time, i.e., it should point to the index of exception registration // for the upper scope. Normally, we will set this value either at // OpCode.Bounce or at OpCode.CallR. But for the top-most language // block, it doesnt start from there, so here we manully set its // ParentIndex to the default system exception registration instance. // // If we can consolidate the updating code at OpCode.Bounce and at // OpCode.CallR, then it is not necessary to manually add this one. // (The reason that we have to do that is because we need the value // of pc in the upper scope, i.e., where does the execution jump to // other function call or language block; otherwise Execute() is a // ideal place to put that updating code). Should refactor this piece // of code for that case. -- Yu Ke TopMostAssocBlockRegistration = ExceptionTable.Register(0, invalidIndex, invalidIndex); TopMostAssocBlockRegistration.ParentIndex = SystemRegistration.RegistrationTableIndex; CurrentActiveRegistration = TopMostAssocBlockRegistration; IsStackUnwinding = false; TargetHandler = null; Context = null; Observers = new List<IFirstHandExceptionObserver>(); }
/// <summary> /// Register an ExceptionRegistration instance for a scope. It is identified /// by three parameters: code block id, function index and class index. /// </summary> /// <param name="codeBlockId"></param> /// <param name="functionScope"></param> /// <param name="classScope"></param> /// <returns></returns> public ExceptionRegistration Register(int codeBlockId, int functionScope, int classScope) { int index = IndexOf(codeBlockId, functionScope, classScope); if (index != ProtoCore.DSASM.Constants.kInvalidIndex) { return Registrations[index]; } ExceptionRegistration registration = new ExceptionRegistration(codeBlockId, functionScope, classScope); Registrations.Add(registration); registration.RegistrationTableIndex = Registrations.Count - 1; // reg.ParentIndex will be set at run-time because at this moment // we have no idea about its calling context return registration; }