blueloveTH 3 лет назад
Родитель
Сommit
79158fb4cd
3 измененных файлов с 28 добавлено и 21 удалено
  1. 1 0
      src/error.h
  2. 10 15
      src/vm.h
  3. 17 6
      tests/_exception.py

+ 1 - 0
src/error.h

@@ -9,6 +9,7 @@ struct NeedMoreLines {
 
 
 struct HandledException {};
 struct HandledException {};
 struct UnhandledException {};
 struct UnhandledException {};
+struct ToBeRaisedException {};
 
 
 enum CompileMode {
 enum CompileMode {
     EXEC_MODE,
     EXEC_MODE,

+ 10 - 15
src/vm.h

@@ -29,7 +29,7 @@ class VM {
         while(frame->has_next_bytecode()){
         while(frame->has_next_bytecode()){
             const Bytecode& byte = frame->next_bytecode();
             const Bytecode& byte = frame->next_bytecode();
             // if(frame->_module != builtins){
             // if(frame->_module != builtins){
-            //     printf("%d: %s (%d) %s\n", frame->get_ip(), OP_NAMES[byte.op], byte.arg, frame->stack_info().c_str());
+            //     printf("%d: %s (%d) %s\n", frame->_ip, OP_NAMES[byte.op], byte.arg, frame->stack_info().c_str());
             // }
             // }
             switch (byte.op)
             switch (byte.op)
             {
             {
@@ -558,10 +558,10 @@ public:
                 ret = run_frame(frame);
                 ret = run_frame(frame);
 
 
                 if(ret != __py2py_call_signal){
                 if(ret != __py2py_call_signal){
+                    callstack.pop();
                     if(frame->id == base_id){      // [ frameBase<- ]
                     if(frame->id == base_id){      // [ frameBase<- ]
-                        break;
+                        return ret;
                     }else{
                     }else{
-                        callstack.pop();
                         frame = callstack.top().get();
                         frame = callstack.top().get();
                         frame->push(ret);
                         frame->push(ret);
                     }
                     }
@@ -575,20 +575,15 @@ public:
                 _Exception& _e = PyException_AS_C(obj);
                 _Exception& _e = PyException_AS_C(obj);
                 _e.st_push(frame->curr_snapshot());
                 _e.st_push(frame->curr_snapshot());
                 callstack.pop();
                 callstack.pop();
-
-                if(!callstack.empty()){
-                    frame = callstack.top().get();
-                    if(frame->id < base_id) throw e;
-                    frame->push(obj);
-                    need_raise = true;
-                    continue;
-                }
-                throw _e;
+                if(callstack.empty()) throw _e;
+                frame = callstack.top().get();
+                frame->push(obj);
+                if(frame->id < base_id) throw ToBeRaisedException();
+                need_raise = true;
+            }catch(ToBeRaisedException& e){
+                need_raise = true;
             }
             }
         }
         }
-
-        callstack.pop();
-        return ret;
     }
     }
 
 
     PyVar new_user_type_object(PyVar mod, _Str name, PyVar base){
     PyVar new_user_type_object(PyVar mod, _Str name, PyVar base){

+ 17 - 6
tests/_exception.py

@@ -1,16 +1,27 @@
+class A:
+    def __getitem__(self, i):
+        raise KeyError(i)
+
+try:
+    a = A()
+    b = a[1]
+except:
+    print("PASS 01")
+
 try:
 try:
-    raise KeyError
+    a = {'1': 3, 4: None}
+    x = a[1]
 except:
 except:
-    print("exception caught")
-print(123)
+    print("PASS 02")
+assert True
 
 
 def f():
 def f():
     try:
     try:
         raise KeyError('foo')
         raise KeyError('foo')
     except A:   # will fail to catch
     except A:   # will fail to catch
-        print("xx")
+        assert False
     except:
     except:
-        print("exception caught")
-    print(123)
+        print("PASS 03")
+    assert True
 
 
 f()
 f()