瀏覽代碼

fix exception

blueloveTH 1 年之前
父節點
當前提交
360efc0805
共有 7 個文件被更改,包括 13 次插入25 次删除
  1. 2 3
      include/pocketpy/codeobject.h
  2. 0 1
      include/pocketpy/expr.h
  3. 0 2
      include/pocketpy/frame.h
  4. 1 1
      src/codeobject.cpp
  5. 1 5
      src/expr.cpp
  6. 8 12
      src/frame.cpp
  7. 1 1
      src/vm.cpp

+ 2 - 3
include/pocketpy/codeobject.h

@@ -42,13 +42,12 @@ inline const int BC_KEEPLINE = -1;
 struct CodeBlock {
     CodeBlockType type;
     int parent;         // parent index in blocks
-    int base_stack_size; // this is used for exception handling
     int start;          // start index of this block in codes, inclusive
     int end;            // end index of this block in codes, exclusive
     int end2;           // ...
 
-    CodeBlock(CodeBlockType type, int parent, int base_stack_size, int start):
-        type(type), parent(parent), base_stack_size(base_stack_size), start(start), end(-1), end2(-1) {}
+    CodeBlock(CodeBlockType type, int parent, int start):
+        type(type), parent(parent), start(start), end(-1), end2(-1) {}
 
     int get_break_end() const{
         if(end2 != -1) return end2;

+ 0 - 1
include/pocketpy/expr.h

@@ -104,7 +104,6 @@ struct CodeEmitContext{
 
     int curr_iblock = 0;
     bool is_compiling_class = false;
-    int base_stack_size = 0;
 
     std::map<PyVar, int> _co_consts_nonstring_dedup_map;
     std::map<std::string, int, std::less<>> _co_consts_string_dedup_map;

+ 0 - 2
include/pocketpy/frame.h

@@ -102,8 +102,6 @@ struct Frame {
             : _ip(co->codes.data()-1), _sp_base(p0), co(co.get()), _module(_module), _callable(nullptr), _locals(co.get(), p0) {}
 
     PyVar* actual_sp_base() const { return _locals.a; }
-
-    int stack_size(ValueStack* _s) const { return _s->_sp - actual_sp_base(); }
     ArgsView stack_view(ValueStack* _s) const { return ArgsView(actual_sp_base(), _s->_sp); }
 
     [[nodiscard]] int prepare_jump_exception_handler(ValueStack*);

+ 1 - 1
src/codeobject.cpp

@@ -4,7 +4,7 @@ namespace pkpy{
 
     CodeObject::CodeObject(std::shared_ptr<SourceData> src, const Str& name):
         src(src), name(name), nlocals(0), start_line(-1), end_line(-1) {
-            blocks.push_back(CodeBlock(CodeBlockType::NO_BLOCK, -1, 0, 0));
+            blocks.push_back(CodeBlock(CodeBlockType::NO_BLOCK, -1, 0));
         }
 
     PyVar const PY_OP_CALL(Type(), new PyObject(Type()));

+ 1 - 5
src/expr.cpp

@@ -24,17 +24,13 @@ namespace pkpy{
     }
 
     CodeBlock* CodeEmitContext::enter_block(CodeBlockType type){
-        if(type==CodeBlockType::FOR_LOOP || type==CodeBlockType::CONTEXT_MANAGER) base_stack_size++;
-        co->blocks.push_back(CodeBlock(
-            type, curr_iblock, base_stack_size, (int)co->codes.size()
-        ));
+        co->blocks.push_back(CodeBlock(type, curr_iblock, (int)co->codes.size()));
         curr_iblock = co->blocks.size()-1;
         return &co->blocks[curr_iblock];
     }
 
     void CodeEmitContext::exit_block(){
         auto curr_type = co->blocks[curr_iblock].type;
-        if(curr_type == CodeBlockType::FOR_LOOP || curr_type==CodeBlockType::CONTEXT_MANAGER) base_stack_size--;
         co->blocks[curr_iblock].end = co->codes.size();
         curr_iblock = co->blocks[curr_iblock].parent;
         if(curr_iblock < 0) PK_FATAL_ERROR();

+ 8 - 12
src/frame.cpp

@@ -24,20 +24,16 @@ namespace pkpy{
     }
 
     int Frame::prepare_jump_exception_handler(ValueStack* _s){
+        PyVar obj = _s->popx();
         // try to find a parent try block
-        int block = co->lines[ip()].iblock;
-        while(block >= 0){
-            if(co->blocks[block].type == CodeBlockType::TRY_EXCEPT) break;
-            block = co->blocks[block].parent;
+        int i = co->lines[ip()].iblock;
+        while(i >= 0){
+            if(co->blocks[i].type == CodeBlockType::TRY_EXCEPT) break;
+            i = _exit_block(_s, i);
         }
-        if(block < 0) return -1;
-        PyVar obj = _s->popx();         // pop exception object
-        // get the stack size of the try block
-        int _stack_size = co->blocks[block].base_stack_size;
-        if(stack_size(_s) < _stack_size) throw std::runtime_error(_S("invalid state: ", stack_size(_s), '<', _stack_size).str());
-        _s->reset(actual_sp_base() + _locals.size() + _stack_size);          // rollback the stack   
-        _s->push(obj);                                      // push exception object
-        return co->blocks[block].end;
+        _s->push(obj);
+        if(i < 0) return -1;
+        return co->blocks[i].end;
     }
 
     int Frame::_exit_block(ValueStack* _s, int i){

+ 1 - 1
src/vm.cpp

@@ -909,7 +909,7 @@ void VM::__init_builtin_types(){
     validate(tp_none_type, new_type_object(nullptr, "NoneType", tp_object, false));
     validate(tp_not_implemented, new_type_object(nullptr, "NotImplementedType", tp_object, false));
     validate(tp_ellipsis, new_type_object(nullptr, "ellipsis", tp_object, false));
-    validate(tp_stack_memory, new_type_object<StackMemory>(nullptr, "stack_memory", tp_object, false));
+    validate(tp_stack_memory, new_type_object<StackMemory>(nullptr, "_stack_memory", tp_object, false));
 
     // SyntaxError and IndentationError must be created here
     PyVar SyntaxError = new_type_object(nullptr, "SyntaxError", tp_exception, true);