}catch(异常范例){
城市跳转到fianlly段举办后续处理惩罚。假如finally不存在,退出当前TryContext上下文, 并继承往后执行。
当一个异常产生时,会从挪用栈栈顶的执行上下文的Try栈举办查找,假如存在某个try-catch可以或许捕捉该异常,则进入该try-catch的catch段或finally端执行。不然退栈处理惩罚,直至碰着对应的try-catch或竣事VM执行。
ENDF // end finally
try-catch的异常处理惩罚机制,支持嵌套。假如异常没有在当前被捕捉上,则会沿着挪用栈继承往外抛出,直到最终被捕捉,或措施因该异常无捕捉而终止执行。
该方案今朝正处在代码归并阶段,不必然代表最终方案。THROWIFNOTbool // Pop the top element in stack, if false, then throw an vm exception
当执行碰着ENDT或ENDC指令时
会先去执行finally段,再从头向外抛出该异常,并退出当前trycontext上下文。
try{
07: ENDT
catch
在Neo3-VM中,主要处理惩罚非运行时的异常,即用户通过throw指令,显示触发的异常。并在内部抽象了一个可捕捉的异常抽象类:CatchableException, 将来可按照需要拓展差异范例的异常。
0c: ENDC // end catch
运行时异常
若异常自己产生在catch段
0b: PUSH2 // catch position
最外层的try-catch将会捕捉到第二个异常,并跳转到catch段,,执行PUSH2。当catch段执行竣事后,会继承跳转到finally段,执行PUSH3,最后执行ENDF竣事该异常处理惩罚。最终,计较栈中的数据为: 栈顶为3,栈底为2。
什么是异常?
10: RET
当执行碰着TRY指令时
return z
会直接抛出该异常,并退出当前trycontext上下文。
留意:若RET指令呈此刻TRY段中,并不会再去Finally执行,此时会直接返回。需要编译器在编译上层语言时,对齐举办处理惩罚,好比C#中,会将try内的return指令,酿成JMP指令。
0f: ENDF // end finally
会在当前执行上下文中,建设一个新的TryContext上下文,并配置其try,catch,finally各段的地点,并配置当前状态为监控状态。
RuntimeException
}
throw error //This error will be throwed outer layer在内部try-catch中,执行try段时,会由于throw指令,用户主动抛出异常,并被捕捉去执行该catch段。可是,在执行catch段,又碰着第二个throw指令。此时,内部try-catch没有finally段,会直接将改异常往外抛。
0d: RET
ENDC // end catch
return x
Exception, 措施自己可以处理惩罚的异常,有细分为如下两类:
}finally{
return y
06: THROW
finally
运行时异常觉得的所有异常
指令设计
措施中可以选择捕捉这些异常处理惩罚,也可以选择不捕捉处理惩罚。这些异常一般是由措施逻辑错误引起的,措施应该从逻辑角度只管制止此类异常的产生。呈现运行时异常后,假如没有捕捉处理惩罚此异常,系统会把异常一层层往上抛,一直到最上层,假如仍未被捕捉上,则会竣事该段措施执行。常见的范例有:空指针异常,数组越界,合约不存在,除数为零等。
异常范例
在Neo3-VM中,回收如下机制举办异常处理惩罚。新增了TryContext上下文,记录当前Try信息,包罗了try-catch的各段的起始位置,以及当前TryContext上下文所处状态(总共三类状态:try监控状态,catch捕捉阶段,finally扫尾阶段)。并在当前执行上下文 ExecutionContext中,添加TryStack栈,记录当前执行进程中,碰着的try-catch信息,即支持try-catch嵌套。
00: TRY
//….
// 监控区域,执行大概发生异常的代码
如其他合约中界说的异常,以及用户本身界说的一些异常。这些异常一般通过显示的挪用throw指令举办抛出。
在异常机制引入之前,常操作if-else的方法处理惩罚异常。然而这种处理惩罚异常方法较量贫苦,同一个异常可能错误假如在多个处所呈现,那么在每个处所都要做沟通处理惩罚,形成许多成果沟通的冗余代码。
若异常产生在finally段
0e: PUSH3 // finally position
08: THROW
throw error // This new error will be throwed outer layer
try
THROWIFbool // Pop the top element in stack, if true, then throw an vm exception
会退出当前TryContext上下文,并继承执行。
对比起单语言,一个公链往往会有多个差异语言版本的实现,确保差异语言差异平台下的对异常触发确定性和一致性变得尤为重要。
0a: ENDT
ENDT // end try
Neo3-VM的异常机制实现道理
异常的通报
常见将异常分为如下几大类:假如只有try-catch布局,缺少finally布局时。
若只有try-finally布局,缺少catch布局时。
1) 若在catch段执行进程中再产生异常,则会直接对外抛出该新异常,并竣事退出该段执行。
给各人举几个非凡场景的环境: Error,措施无法处理惩罚的异常,暗示运行中呈现较严重的问题。大大都错误与代码编写者的操纵无关,而是代码运行时呈现的问题,并往往导致措施无律例复举办。如常见的内存溢出,内存不足,栈溢出等。 郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。
try
若try和finally段中,都包括return语句时。
try
// 善后处理惩罚,无论是否产生异常,代码城市执行
NonRuntimeException
catch
01: 0x0b0e // catch -> 0b, finallyOffset = 0e
3)最终会执行finally段的return, 可是返回值按照差异语言的实现,有的能返回finally的值,有的是返回try段的值。故在实际中,并不是很勉励在finally段利用return指令。
// 捕捉,举办异常处理惩罚操纵
//…
2)若在finally段执行进程中再产生异常,则会直接对外抛出该新异常,并竣事该段执行。
设计精采的措施应该在措施异常产生时提供处理惩罚这些异常的要领,使得措施不会因为异常的产生而阻断或发生不行预见的功效。譬喻,一笔付出金额不敷或付出失败时,需要规复继承执行其他操纵等。
TRY catchOffset, finallyOffset // try-catch-finally 起始位置,需要拟定catch, finally各自偏移量。假如catch段不存在,则偏移量catchOffset为0;假如finally段不存在,则偏移量finallyOffset为0
//..
此刻常用的方法,回收try-catch机制来处理惩罚异常,其根基道理如下:
异常的处理惩罚机制
03: TRY
THROW // It will throw an vm exception
…
在Neo-VM的指令中,try-catch总共包括四个指令,throw类三个指令,各自成果如下:
中的异常处理惩罚特性
//….
//…
//…
//…
异常是指在措施运行的进程中产生的一些不正常事件。如除0溢出,数组下标越界,需要进动作态挪用的合约不存在等。
…
一个带try-catch嵌套的Neo3-VM字节措施例子:
当执行碰着ENDF指令时
…