看看openjdk中的athrow处理流程
{
oop except_oop = STACK_OBJECT(-1); //从栈中弹出异常的引用
CHECK_NULL(except_oop); //检查异常引用是否为空
THREAD->set_pending_exception(except_oop, NULL, 0);
goto handle_exception; //处理异常执行代码
}
处理异常的代码handle_exception
{
Handle except_oop(THREAD, THREAD->pending_exception());
CALL_VM(continuation_bci = (intptr_t)InterpreterRuntime::exception_handler_for_exception(THREAD, except_oop()), handle_exception); //此为查找异常表,也就是执行InterpreterRuntime::exception_handler_for_exception,如果在执行的过程中还抛出异常,回到handle_exception开始地方,继续执行
except_oop = (oop) THREAD->vm_result();
THREAD->set_vm_result(NULL);
if (continuation_bci >= 0) { //一般都是大于0,详见查找异常表exception_handler_for_exception的操作的说明
SET_STACK_OBJECT(except_oop(), 0);
MORE_STACK(1);
pc = METHOD->code_base() + continuation_bci; //pc指针
............
goto run ; //转到解释器处理循环,如果到这,不会执行if以后的代码
}
THREAD->set_pending_exception(except_oop(), NULL, 0);
goto handle_return; //本方法没有找到相应的异常处理,继续往上抛出
}
先看看查找异常表的代码
InterpreterRuntime::exception_handler_for_exception(JavaThread* thread, oopDesc* exception)
{
.............
if (thread->do_not_unlock_if_synchronized()) {
return Interpreter::remove_activation_entry();
}
do {
KlassHandle h_klass(THREAD, h_exception->klass());
handler_bci = h_method->fast_exception_handler_bci_for(h_klass, current_bci, THREAD);
if (HAS_PENDING_EXCEPTION) { //需要处理异常
h_exception = Handle(THREAD, PENDING_EXCEPTION);
CLEAR_PENDING_EXCEPTION;
if (handler_bci >= 0) { //这个地方有点看不明白,大于0应该是表示找到了catch里面对应的异常处理,怎么还继续循环?
current_bci = handler_bci;
should_repeat = true;
}
}
}while (should_repeat == true);
address continuation = NULL;
if (handler_bci < 0 || !thread->reguard_stack((address) &continuation)) {
continuation = Interpreter::remove_activation_entry();
h_method->interpreter_throwout_increment();
}else{
handler_pc = h_method->code_base() + handler_bci;
set_bcp_and_mdp(handler_pc, thread);
continuation = Interpreter::dispatch_table(vtos)[*handler_pc];
}
thread->set_vm_result(h_exception());
return continuation;
}
上面是在本方法里面找到的异常处理的代码,如果没有找到,应该是执行handle_return代码,handle_return处理的应该是本方法没有处理异常,也就是应该由上层方法处理。
handle_return:
{
if (THREAD->do_not_unlock()) { //对方法中监视器的处理
}else{
}
if (illegal_state_oop() != NULL || original_exception() != NULL) {
istate->set_msg(throwing_exception);
if (illegal_state_oop() != NULL)
THREAD->set_pending_exception(illegal_state_oop(), NULL, 0);
else
THREAD->set_pending_exception(original_exception(), NULL, 0);
istate->set_return_kind((Bytecodes::Code)opcode);
UPDATE_PC_AND_RETURN(0);
/*注意,这个地方采用的是return,也就是说它会跳出解释器的while(1)循环,从而结束javaCalls:call方法,这个就返回了上一个方法的处理流程中,具体得看InterpreterGenerator::generate_normal_entry,这个地方有些难于看懂,是怎么从调用的方法中返回,然后进行下一句的执行的。
在generate_normal_entry中注意下面的两句
__ pushptr(return_from_native_method.addr());调用前的返回地址(这就是上面return返回后的地址)
__ jmp(rax); 调用真正的方法
*/
}
}
分享到:
相关推荐
1. **正常执行**:如果没有异常发生,程序会先执行`finally`块中的代码,然后返回结果。 2. **异常发生**:如果在`try`或`catch`块中发生了异常,并且这个异常没有被捕获或被重新抛出,那么在抛出异常之前,会先执行...
此外,代码中还包含了`$jscomp.findInternal`函数的定义,这是一个内部实现的查找方法,用于遍历数组或字符串并执行回调函数。当满足条件时返回匹配的元素及其索引,否则返回默认值。 以上就是从给定的文件中提取的...
总之,对于微信小程序的同步执行需求,开发者可以根据项目实际情况选择合适的方法,但通常建议优先考虑使用async/await,以提高代码质量。同时,了解和掌握这两种方法有助于更好地应对复杂的异步编程挑战。
异常是在程序执行过程中发生的非正常事件,可能导致程序无法继续正常运行。C++通过异常处理机制提供了一种在运行时捕获和处理错误的方式,而不是通过返回值或全局变量。 ### 2. `try`块 `try`块是异常处理的核心...
4. **继承(Inheritance)**:一个类可以继承另一个类的属性和方法,形成“is-a”关系,实现代码复用和类层次结构。 5. **多态性(Polymorphism)**:多态性允许不同类的对象对同一消息作出不同的响应,常通过虚...
- 使用`async`和`await`关键字可以编写非阻塞的异步代码,提高程序性能。 - `Task`和`Task<T>`是异步编程的核心类型。 9. **扩展方法**: - 扩展方法允许你在不修改已有类的情况下向其添加新方法,提高了代码的...
例如,你可以创建一个名为`Calculator`的类,并在其中定义`+`、`-`、`*`和`/`的方法,以执行相应的计算。 首先,我们需要定义一个`Calculator`类,它通常包含以下成员: ```csharp public class Calculator { ...
2. (第2题) 定义方法void sanjiao(int a,int b,int c)中,不符合条件则抛出异常(if a+b(或a+c,b+c<=a) then throw new IllegalArgumentException(),),再定义main方法,调用此方法,用try…..catch…. finally语句并...
5. **异常处理指令**:`athrow`用于抛出一个异常,`catch`配合try-catch块捕获异常。 6. **多线程指令**:如`synchronized`用于同步代码块或方法,保证并发环境下的线程安全。 7. **方法和类操作指令**:如`return...
9. **异常处理**:`athrow`用于抛出异常,`catch`块和`finally`块的字节码实现。 10. **类型转换**:如`i2d`(将int转换为double),`checkcast`用于类型检查和强制转换。 Java指令集是JVM运行Java程序的关键,它...
throw new CustomException("A custom error message."); } } ``` 2. **捕获和处理异常**: 当你抛出一个异常后,通常需要在上层代码中捕获并处理它。这通过 `try-catch` 块实现。在 `try` 块中包含可能抛出...
在Visual Studio 2008中,你可以创建一个新的控制台应用程序项目,将上述代码粘贴到`Program.cs`文件中,然后运行程序以测试运算器功能。这个简单的运算器可以作为一个基础,通过添加更多的功能,如支持浮点数、括号...
其次,避免执行未经验证的用户输入,防止恶意代码执行。最后,对于客户端,应确保用户已明确知晓并同意这样的操作,否则可能引发隐私和安全风险。 四、跨平台支持 不同的操作系统可能有不同的方式来执行exe文件。...
当程序检测到某种条件不符合预期时,可以通过`throw`来抛出一个异常,这样可以让调用者或更高层次的处理代码意识到发生了错误并采取相应的措施。 ##### 语法格式 ```java throw (异常对象); ``` 例如: ```java ...
当在`finally`块中使用`throw`语句时,它会立即中断`finally`块的执行,并将控制权交回给最近的`catch`块,如果没有`catch`块,则程序会终止。 在描述中提到的"The Date Constructor Called as a Function"是指`...
在IT行业中,动态链接库(DLL)是一种非常重要的技术,它允许多个程序共享同一段代码和数据,从而节省系统资源,提高程序执行效率。本文将详细介绍如何在Visual Studio 2013环境下创建、封装及调用DLL,并提供内附的...
反射是Java中的一种强大工具,允许程序在运行时检查类、接口、字段和方法的信息,并动态地调用方法或访问字段。通过`Class`类和`java.lang.reflect`包中的其他类,我们可以实现对对象的元数据操作。例如,以下代码...
throw关键字可以用来抛出任何类型的异常,但是一旦被执行,程序就会立即转入异常处理阶段,后面的语句就不再执行了。 Throws和Throw的区别 throws和throw关键字之间存在着明显的区别。throws关键字是用来声明方法...
在Java中,异常是程序执行期间发生的错误,可以是编译时错误、运行时错误或检查性异常。异常处理通过`try-catch-finally`语句块来实现,使得我们可以在遇到异常时优雅地恢复程序,而不是让程序崩溃。例如: ```java...
当一个异常发生时,程序会在内存堆中创建一个异常对象,停止当前执行路径,并开始寻找合适的异常处理器来恢复程序执行或终止程序。 Java中的异常处理有三个关键字:`try`、`catch`和`finally`。`try`块包含可能抛出...