@@ -37,6 +37,7 @@ public class Statement : IBytecode, IStatement<StatementComponent>
3737
3838 public Stack Evaluate ( RuntimeBase vm , Stack stack )
3939 {
40+ bool caught = false ;
4041 try
4142 {
4243 foreach ( var component in Main )
@@ -51,6 +52,57 @@ public Stack Evaluate(RuntimeBase vm, Stack stack)
5152 stack [ Default ] ! [ vm , stack , i ] = stack . Bet ? [ vm , stack , 0 ] ?? IObject . Null ;
5253 }
5354
55+ break ;
56+ case ( StatementComponentType . Code , BytecodeType . StmtTry ) :
57+ ( string name , IObject value ) [ ] ? resources = null ;
58+ var comp = Main [ 0 ] ;
59+ try
60+ {
61+ if ( comp . ByteArg == 1 ) // try-with-resources
62+ resources = comp . SubStatement ! . Main . Select ( x => ( x . Args [ 1 ] ,
63+ x . SubComponent ! . Evaluate ( vm , stack . Output ( ) ) . Copy ( ) ! [ vm , stack , 0 ] ) ) . ToArray ( ) ;
64+
65+ var resourcesF = resources ;
66+ var compF = comp ;
67+ stack . StepInside ( vm , comp . SourcefilePosition , "try" , stack =>
68+ {
69+ foreach ( var resource in resourcesF ?? Array . Empty < ( string , IObject ) > ( ) )
70+ vm . PutLocal ( stack , resource . name , resource . value ) ;
71+ compF . InnerCode ! . Evaluate ( vm , stack ) ;
72+ } ) ;
73+ }
74+ catch ( StackTraceException trace )
75+ {
76+ var innerCause = trace . InnerCause . Obj ;
77+ foreach ( var catchBlock in CatchFinally ! . SubStatement ! . Main
78+ . Where ( x => x . Args . Select ( t => vm . FindType ( t ) )
79+ . Any ( x => x ! . CanHold ( innerCause . Type ) ) )
80+ . Select ( x => ( x . Arg , x . InnerCode ) ) )
81+ {
82+ stack . StepInside ( vm , CatchFinally . SourcefilePosition , "catch" , stack =>
83+ {
84+ vm . PutLocal ( stack , catchBlock . Arg , innerCause ) ;
85+ catchBlock . InnerCode ! . Evaluate ( vm , stack ) ;
86+ } ) ;
87+ }
88+ caught = true ;
89+ }
90+ finally
91+ {
92+ try
93+ {
94+ if ( resources != null )
95+ foreach ( var resource in resources . Select ( x => x . value ) )
96+ Class . CloseableType . DeclaredMembers [ "close" ] . Invoke ( vm , stack , resource ) ;
97+ CatchFinally ! . AltComponent ! . InnerCode ! . Evaluate ( vm , stack ) ;
98+ caught = true ;
99+ }
100+ catch ( StackTraceException fatal )
101+ {
102+ throw new FatalException ( "Inner exception during finalization" , fatal ) ;
103+ }
104+ }
105+
54106 break ;
55107 default :
56108 component . Evaluate ( vm , stack ) ;
@@ -63,16 +115,23 @@ public Stack Evaluate(RuntimeBase vm, Stack stack)
63115 }
64116 catch ( InternalException codeEx )
65117 {
66- if ( CatchFinally != null )
67- CatchFinally . Evaluate ( vm , stack ) ;
118+ stack [ Tau ] = new ObjectRef ( Class . ThrowableType . DefaultInstance , codeEx . Obj ) ;
119+ CatchFinally ? . Evaluate ( vm , stack ) ;
120+ caught = true ;
68121 throw codeEx ;
69122 }
70123 catch ( StackTraceException codeEx )
71124 {
72- if ( CatchFinally != null )
73- CatchFinally . Evaluate ( vm , stack ) ;
125+ stack [ Tau ] = new ObjectRef ( Class . ThrowableType . DefaultInstance , codeEx . InnerCause . Obj ) ;
126+ CatchFinally ? . Evaluate ( vm , stack ) ;
127+ caught = true ;
74128 throw codeEx ;
75129 }
130+ finally
131+ {
132+ if ( ! caught )
133+ CatchFinally ? . AltComponent ? . InnerCode ! . Evaluate ( vm , stack ) ;
134+ }
76135
77136 return stack ;
78137 }
@@ -88,6 +147,7 @@ public class StatementComponent : IBytecode, IStatementComponent
88147 public Statement Statement { get ; set ; } = null ! ;
89148 public VariableContext VariableContext { get ; set ; }
90149 public string Arg { get ; set ; } = string . Empty ;
150+ public List < string > Args { get ; set ; } = new ( ) ;
91151 public ulong ByteArg { get ; set ; }
92152 public SourcefilePosition SourcefilePosition { get ; set ; }
93153 public Statement ? SubStatement { get ; set ; }
@@ -223,6 +283,7 @@ public virtual Stack Evaluate(RuntimeBase vm, Stack stack)
223283 SubComponent . Evaluate ( vm , stack . Output ( ) ) . Copy ( output : Alp | Omg ) ;
224284 //Console.WriteLine(stack[Alp]);
225285 stack . State = State . Throw ;
286+ Stack . StackTrace . Clear ( ) ;
226287 break ;
227288 case ( StatementComponentType . Code , BytecodeType . StmtIf ) :
228289 stack . StepInside ( vm , SourcefilePosition , "if" , stack =>
@@ -283,6 +344,20 @@ public virtual Stack Evaluate(RuntimeBase vm, Stack stack)
283344 } while ( SubComponent . Evaluate ( vm , stack . Output ( Phi ) ) . Copy ( Phi ) . ToBool ( ) ) ;
284345 } ) ;
285346 break ;
347+ case ( StatementComponentType . Code , BytecodeType . StmtCatch ) :
348+ IObject ex = stack [ Tau ] ! [ vm , stack , 0 ] ;
349+ IClassInfo exType = ex . Type ;
350+ try
351+ {
352+ SubStatement ! . Main
353+ . FirstOrDefault ( comp => comp . Args . Any ( exClsName => exClsName == exType . CanonicalName ) )
354+ ? . InnerCode ! . Evaluate ( vm , stack ) ;
355+ }
356+ finally
357+ {
358+ AltComponent ? . InnerCode ! . Evaluate ( vm , stack ) ;
359+ }
360+ break ;
286361 case ( StatementComponentType . Operator , _ ) :
287362 var op = ( Operator ) ByteArg ;
288363 var compound = ( op & Operator . Compound ) == Operator . Compound ;
0 commit comments