private void ThrowInstruction(Context context) { var method = PlatformInternalRuntimeType.FindMethodByName("ExceptionHandler"); context.SetInstruction(Select(exceptionRegister, IRInstruction.MoveInt32, IRInstruction.MoveInt64), exceptionRegister, context.Operand1); context.AppendInstruction(IRInstruction.CallStatic, null, Operand.CreateSymbolFromMethod(method, TypeSystem)); MethodScanner.MethodInvoked(method, Method); }
private MosaMethod GetVMCallMethod(VmCall vmcall) { string methodName = vmcall.ToString(); var method = InternalRuntimeType.FindMethodByName(methodName) ?? PlatformInternalRuntimeType.FindMethodByName(methodName); Debug.Assert(method != null, "Cannot find method: " + methodName); return(method); }
private void ThrowInstruction(InstructionNode node) { var method = PlatformInternalRuntimeType.FindMethodByName("ExceptionHandler"); var ctx = new Context(node); ctx.SetInstruction(IRInstruction.MoveInteger, exceptionRegister, node.Operand1); //ctx.AppendInstruction(IRInstruction.KillAllExcept, null, exceptionRegister); ctx.AppendInstruction(IRInstruction.CallStatic, null, Operand.CreateSymbolFromMethod(method, TypeSystem)); }
protected override void Setup() { exceptionVirtualRegisters = new Dictionary <BasicBlock, Operand>(); leaveTargetVirtualRegisters = new Dictionary <BasicBlock, Operand>(); leaveTargets = new List <BasicBlock>(); if (exceptionHandler == null) { exceptionHandler = PlatformInternalRuntimeType.FindMethodByName("ExceptionHandler"); exceptionHandlerMethod = Operand.CreateSymbolFromMethod(exceptionHandler, TypeSystem); } CollectLeaveTargets(); }
private void FinallyEndInstruction(InstructionNode node) { var header = FindImmediateExceptionContext(node.Label); var headerBlock = BasicBlocks.GetByLabel(header.HandlerStart); var exceptionVirtualRegister = exceptionVirtualRegisters[headerBlock]; var newBlocks = CreateNewBlockContexts(1); var ctx = new Context(node); var nextBlock = Split(ctx); ctx.SetInstruction(IRInstruction.CompareIntegerBranch, ConditionCode.NotEqual, null, exceptionVirtualRegister, nullOperand, newBlocks[0].Block); ctx.AppendInstruction(IRInstruction.Jmp, nextBlock.Block); var method = PlatformInternalRuntimeType.FindMethodByName("ExceptionHandler"); newBlocks[0].AppendInstruction(IRInstruction.MoveInteger, exceptionRegister, exceptionVirtualRegister); newBlocks[0].AppendInstruction(IRInstruction.CallStatic, null, Operand.CreateSymbolFromMethod(method, TypeSystem)); }
private void FinallyEndInstruction(Context context) { var header = FindImmediateExceptionContext(context.Label); var headerBlock = BasicBlocks.GetByLabel(header.HandlerStart); var exceptionVirtualRegister = exceptionVirtualRegisters[headerBlock]; var newBlocks = CreateNewBlockContexts(1, context.Label); var nextBlock = Split(context); context.SetInstruction(Select(IRInstruction.CompareIntBranch32, IRInstruction.CompareIntBranch64), ConditionCode.NotEqual, null, exceptionVirtualRegister, nullOperand, newBlocks[0].Block); context.AppendInstruction(IRInstruction.Jmp, nextBlock.Block); var method = PlatformInternalRuntimeType.FindMethodByName("ExceptionHandler"); newBlocks[0].AppendInstruction(Select(exceptionRegister, IRInstruction.MoveInt32, IRInstruction.MoveInt64), exceptionRegister, exceptionVirtualRegister); newBlocks[0].AppendInstruction(IRInstruction.CallStatic, null, Operand.CreateSymbolFromMethod(method, TypeSystem)); MethodScanner.MethodInvoked(method, Method); }
protected override void Run() { exceptionVirtualRegisters = new Dictionary <BasicBlock, Operand>(); finallyReturnVirtualRegisters = new Dictionary <BasicBlock, Operand>(); exceptionType = TypeSystem.GetTypeByName("System", "Exception"); var exceptionRegister = Operand.CreateCPURegister(exceptionType, Architecture.ExceptionRegister); var finallyReturnBlockRegister = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, Architecture.FinallyReturnBlockRegister); var nullOperand = Operand.GetNull(TypeSystem); for (int i = 0; i < BasicBlocks.Count; i++) { var block = BasicBlocks[i]; for (var node = block.First; !node.IsBlockEndInstruction; node = node.Next) { if (node.IsEmpty) { continue; } if (node.Instruction == IRInstruction.Throw) { var method = PlatformInternalRuntimeType.FindMethodByName("ExceptionHandler"); var ctx = new Context(node); ctx.SetInstruction(IRInstruction.Move, exceptionRegister, node.Operand1); //ctx.AppendInstruction(IRInstruction.KillAllExcept, null, exceptionRegister); ctx.AppendInstruction(IRInstruction.Call, null, Operand.CreateSymbolFromMethod(TypeSystem, method)); ctx.InvokeMethod = method; } else if (node.Instruction == IRInstruction.CallFinally) { var target = node.BranchTargets[0]; var finallyReturn = node.BranchTargets[1]; var ctx = new Context(node); ctx.SetInstruction(IRInstruction.KillAll); ctx.AppendInstruction(IRInstruction.Move, exceptionRegister, nullOperand); ctx.AppendInstruction(IRInstruction.Move, finallyReturnBlockRegister, Operand.CreateConstant(TypeSystem, finallyReturn.Label)); ctx.AppendInstruction(IRInstruction.Jmp, target); } else if (node.Instruction == IRInstruction.FinallyStart) { // Remove from header blocks BasicBlocks.RemoveHeaderBlock(node.Block); var exceptionVirtualRegister = node.Result; var finallyReturnBlockVirtualRegister = node.Result2; var ctx = new Context(node); exceptionVirtualRegisters.Add(node.Block, exceptionVirtualRegister); finallyReturnVirtualRegisters.Add(node.Block, finallyReturnBlockRegister); ctx.SetInstruction(IRInstruction.KillAll); ctx.AppendInstruction(IRInstruction.Gen, exceptionRegister); ctx.AppendInstruction(IRInstruction.Gen, finallyReturnBlockRegister); ctx.AppendInstruction(IRInstruction.Move, exceptionVirtualRegister, exceptionRegister); ctx.AppendInstruction(IRInstruction.Move, finallyReturnBlockVirtualRegister, finallyReturnBlockRegister); } else if (node.Instruction == IRInstruction.FinallyEnd) { var header = FindImmediateExceptionHandler(node); var headerBlock = BasicBlocks.GetByLabel(header.HandlerStart); var exceptionVirtualRegister = exceptionVirtualRegisters[headerBlock]; var finallyReturnBlockVirtualRegister = finallyReturnVirtualRegisters[headerBlock]; var newBlocks = CreateNewBlockContexts(1); var ctx = new Context(node); var nextBlock = Split(ctx); ctx.SetInstruction(IRInstruction.IntegerCompareBranch, ConditionCode.NotEqual, null, exceptionVirtualRegister, nullOperand, newBlocks[0].Block); ctx.AppendInstruction(IRInstruction.Jmp, nextBlock.Block); var method = PlatformInternalRuntimeType.FindMethodByName("ExceptionHandler"); newBlocks[0].AppendInstruction(IRInstruction.Move, exceptionRegister, exceptionVirtualRegister); newBlocks[0].AppendInstruction(IRInstruction.Call, null, Operand.CreateSymbolFromMethod(TypeSystem, method)); newBlocks[0].InvokeMethod = method; } else if (node.Instruction == IRInstruction.FinallyReturn) { var targets = node.BranchTargets; var header = FindImmediateExceptionHandler(node); var headerBlock = BasicBlocks.GetByLabel(header.HandlerStart); var finallyReturnBlockVirtualRegister = finallyReturnVirtualRegisters[headerBlock]; Debug.Assert(targets.Count != 0); if (targets.Count == 1) { node.SetInstruction(IRInstruction.Jmp, targets[0]); } else { var newBlocks = CreateNewBlockContexts(targets.Count - 1); var ctx = new Context(node); ctx.SetInstruction(IRInstruction.IntegerCompareBranch, ConditionCode.Equal, null, finallyReturnBlockVirtualRegister, Operand.CreateConstant(TypeSystem, targets[0].Label), targets[0]); ctx.AppendInstruction(IRInstruction.Jmp, newBlocks[0].Block); for (int b = 1; b < targets.Count - 2; b++) { newBlocks[b - 1].AppendInstruction(IRInstruction.IntegerCompareBranch, ConditionCode.Equal, null, finallyReturnBlockVirtualRegister, Operand.CreateConstant(TypeSystem, targets[b].Label), targets[b]); newBlocks[b - 1].AppendInstruction(IRInstruction.Jmp, newBlocks[b + 1].Block); } newBlocks[targets.Count - 2].AppendInstruction(IRInstruction.Jmp, targets[targets.Count - 1]); } } else if (node.Instruction == IRInstruction.ExceptionStart) { var exceptionVirtualRegister = node.Result; var ctx = new Context(node); ctx.SetInstruction(IRInstruction.KillAll); ctx.AppendInstruction(IRInstruction.Gen, exceptionRegister); ctx.AppendInstruction(IRInstruction.Move, exceptionVirtualRegister, exceptionRegister); } else if (node.Instruction == IRInstruction.ExceptionEnd) { node.SetInstruction(IRInstruction.Jmp, node.BranchTargets[0]); } else if (node.Instruction == IRInstruction.Flow) { node.Empty(); } } } }