blueloveTH 3 лет назад
Родитель
Сommit
80e49a677e
11 измененных файлов с 29 добавлено и 27 удалено
  1. 2 2
      src/ceval.h
  2. 1 1
      src/cffi.h
  3. 4 2
      src/common.h
  4. 3 3
      src/compiler.h
  5. 8 8
      src/expr.h
  6. 1 1
      src/gc.h
  7. 4 4
      src/lexer.h
  8. 1 1
      src/namedict.h
  9. 1 1
      src/obj.h
  10. 1 1
      src/pocketpy.h
  11. 3 3
      src/vm.h

+ 2 - 2
src/ceval.h

@@ -13,7 +13,7 @@ inline PyObject* VM::_run_top_frame(){
 
     while(true){
 #if DEBUG_EXTRA_CHECK
-        if(frame->id < base_id) UNREACHABLE();
+        if(frame->id < base_id) FATAL_ERROR();
 #endif
         try{
             if(need_raise){ need_raise = false; _raise(); }
@@ -498,7 +498,7 @@ __NEXT_STEP:;
 #if DEBUG_EXTRA_CHECK
     default: throw std::runtime_error(fmt(OP_NAMES[byte.op], " is not implemented"));
 #else
-    default: std::unreachable();
+    default: UNREACHABLE();
 #endif
     }
 #endif

+ 1 - 1
src/cffi.h

@@ -312,7 +312,7 @@ struct Pointer{
             CASE(double, f64);
             CASE(bool, bool);
 #undef CASE
-            default: UNREACHABLE();
+            default: FATAL_ERROR();
         }
     }
 

+ 4 - 2
src/common.h

@@ -51,8 +51,10 @@
 
 #if _MSC_VER
 #define PK_ENABLE_COMPUTED_GOTO		0
+#define UNREACHABLE()				__assume(0)
 #else
 #define PK_ENABLE_COMPUTED_GOTO		1
+#define UNREACHABLE()				__builtin_unreachable()
 #endif
 
 #if defined(__EMSCRIPTEN__) || defined(__arm__) || defined(__i386__)
@@ -89,9 +91,9 @@ struct Type {
 #define CPP_NOT_IMPLEMENTED() ([](VM* vm, Args& args) { vm->NotImplementedError(); return vm->None; })
 
 #ifdef POCKETPY_H
-#define UNREACHABLE() throw std::runtime_error( "L" + std::to_string(__LINE__) + " UNREACHABLE()!");
+#define FATAL_ERROR() throw std::runtime_error( "L" + std::to_string(__LINE__) + " FATAL_ERROR()!");
 #else
-#define UNREACHABLE() throw std::runtime_error( __FILE__ + std::string(":") + std::to_string(__LINE__) + " UNREACHABLE()!");
+#define FATAL_ERROR() throw std::runtime_error( __FILE__ + std::string(":") + std::to_string(__LINE__) + " FATAL_ERROR()!");
 #endif
 
 inline const float kLocalsLoadFactor = 0.67f;

+ 3 - 3
src/compiler.h

@@ -267,7 +267,7 @@ class Compiler {
             case TK("*"):
                 ctx()->s_expr.push(make_expr<StarredExpr>(ctx()->s_expr.popx()));
                 break;
-            default: UNREACHABLE();
+            default: FATAL_ERROR();
         }
     }
 
@@ -464,7 +464,7 @@ __SUBSCR_END:
         if(is_slice){
             e->b = std::move(slice);
         }else{
-            if(state != 1) UNREACHABLE();
+            if(state != 1) FATAL_ERROR();
             e->b = std::move(slice->start);
         }
         ctx()->s_expr.push(std::move(e));
@@ -936,7 +936,7 @@ public:
     }
 
     CodeObject_ compile(){
-        if(used) UNREACHABLE();
+        if(used) FATAL_ERROR();
         used = true;
 
         tokens = lexer->run();

+ 8 - 8
src/expr.h

@@ -55,7 +55,7 @@ struct CodeEmitContext{
         if(co->blocks[curr_block_i].type == FOR_LOOP) for_loop_depth--;
         co->blocks[curr_block_i].end = co->codes.size();
         curr_block_i = co->blocks[curr_block_i].parent;
-        if(curr_block_i < 0) UNREACHABLE();
+        if(curr_block_i < 0) FATAL_ERROR();
     }
 
     // clear the expression stack and generate bytecode
@@ -137,7 +137,7 @@ struct NameExpr: Expr{
             case NAME_GLOBAL:
                 ctx->emit(OP_DELETE_GLOBAL, index, line);
                 break;
-            default: UNREACHABLE(); break;
+            default: FATAL_ERROR(); break;
         }
         return true;
     }
@@ -155,7 +155,7 @@ struct NameExpr: Expr{
             case NAME_GLOBAL:
                 ctx->emit(OP_STORE_GLOBAL, index, line);
                 break;
-            default: UNREACHABLE(); break;
+            default: FATAL_ERROR(); break;
         }
         return true;
     }
@@ -229,7 +229,7 @@ struct Literal0Expr: Expr{
             case TK("True"):    ctx->emit(OP_LOAD_TRUE, BC_NOARG, line); break;
             case TK("False"):   ctx->emit(OP_LOAD_FALSE, BC_NOARG, line); break;
             case TK("..."):     ctx->emit(OP_LOAD_ELLIPSIS, BC_NOARG, line); break;
-            default: UNREACHABLE();
+            default: FATAL_ERROR();
         }
     }
 
@@ -254,7 +254,7 @@ struct LiteralExpr: Expr{
             return s.str();
         }
 
-        UNREACHABLE();
+        FATAL_ERROR();
     }
 
     PyObject* to_object(CodeEmitContext* ctx){
@@ -274,7 +274,7 @@ struct LiteralExpr: Expr{
 
     void emit(CodeEmitContext* ctx) override {
         PyObject* obj = to_object(ctx);
-        if(obj == nullptr) UNREACHABLE();
+        if(obj == nullptr) FATAL_ERROR();
         int index = ctx->add_const(obj);
         ctx->emit(OP_LOAD_CONST, index, line);
     }
@@ -448,7 +448,7 @@ struct CompExpr: Expr{
         ctx->emit(OP_FOR_ITER, BC_NOARG, BC_KEEPLINE);
         bool ok = vars->emit_store(ctx);
         // this error occurs in `vars` instead of this line, but...nevermind
-        if(!ok) UNREACHABLE();  // TODO: raise a SyntaxError instead
+        if(!ok) FATAL_ERROR();  // TODO: raise a SyntaxError instead
         if(cond){
             cond->emit(ctx);
             int patch = ctx->emit(OP_POP_JUMP_IF_FALSE, BC_NOARG, BC_KEEPLINE);
@@ -672,7 +672,7 @@ struct BinaryExpr: Expr{
             case TK("&"):   ctx->emit(OP_BITWISE_AND, BC_NOARG, line);  break;
             case TK("|"):   ctx->emit(OP_BITWISE_OR, BC_NOARG, line);  break;
             case TK("^"):   ctx->emit(OP_BITWISE_XOR, BC_NOARG, line);  break;
-            default: UNREACHABLE();
+            default: FATAL_ERROR();
         }
     }
 };

+ 1 - 1
src/gc.h

@@ -101,7 +101,7 @@ struct ManagedHeap{
     }
 
     int collect(){
-        if(_gc_lock_counter > 0) UNREACHABLE();
+        if(_gc_lock_counter > 0) FATAL_ERROR();
         mark();
         int freed = sweep();
         return freed;

+ 4 - 4
src/lexer.h

@@ -38,7 +38,7 @@ constexpr TokenIndex TK(const char token[]) {
         while(*i && *j && *i == *j) { i++; j++;}
         if(*i == *j) return k;
     }
-    UNREACHABLE();
+    FATAL_ERROR();
 }
 
 #define TK_STR(t) kTokens[t]
@@ -344,7 +344,7 @@ struct Lexer {
                 } else {
                     add_token(TK("@num"), S_TO_INT(m[0], &size, base));
                 }
-                if (size != m.length()) UNREACHABLE();
+                if (size != m.length()) FATAL_ERROR();
             }
         }catch(std::exception& _){
             SyntaxError("invalid number literal");
@@ -448,7 +448,7 @@ struct Lexer {
                         case 2: SyntaxError("invalid utf8 sequence: " + std::string(1, c));
                         case 3: SyntaxError("@id contains invalid char"); break;
                         case 4: SyntaxError("invalid JSON token"); break;
-                        default: UNREACHABLE();
+                        default: FATAL_ERROR();
                     }
                     return true;
                 }
@@ -494,7 +494,7 @@ struct Lexer {
     }
 
     std::vector<Token> run() {
-        if(used) UNREACHABLE();
+        if(used) FATAL_ERROR();
         used = true;
         while (lex_one_token());
         return std::move(nexts);

+ 1 - 1
src/namedict.h

@@ -119,7 +119,7 @@ while(!_items[i].first.empty()) {       \
             if(old_items[i].first.empty()) continue;
             bool ok; uint16_t j;
             HASH_PROBE(old_items[i].first, ok, j);
-            if(ok) UNREACHABLE();
+            if(ok) FATAL_ERROR();
             _items[j] = old_items[i];
         }
         pool128.dealloc(old_items);

+ 1 - 1
src/obj.h

@@ -183,7 +183,7 @@ inline bool is_type(PyObject* obj, Type type) {
     }                                                                       \
     static PyObject* register_class(VM* vm, PyObject* mod) {                \
         PyObject* type = vm->new_type_object(mod, #name, vm->tp_object);    \
-        if(OBJ_NAME(mod) != #mod) UNREACHABLE();                            \
+        if(OBJ_NAME(mod) != #mod) FATAL_ERROR();                            \
         T::_register(vm, mod, type);                                        \
         type->attr()._try_perfect_rehash();                                 \
         return type;                                                        \

+ 1 - 1
src/pocketpy.h

@@ -978,7 +978,7 @@ extern "C" {
                 case 'N': f_None(packet); return vm->None;
             }
             free(packet);
-            UNREACHABLE();
+            FATAL_ERROR();
             return vm->None;
         });
         return strdup(f_header.c_str());

+ 3 - 3
src/vm.h

@@ -102,7 +102,7 @@ public:
 
     FrameId top_frame() {
 #if DEBUG_EXTRA_CHECK
-        if(callstack.empty()) UNREACHABLE();
+        if(callstack.empty()) FATAL_ERROR();
 #endif
         return FrameId(&callstack.data(), callstack.size()-1);
     }
@@ -553,7 +553,7 @@ inline PyObject* VM::new_module(StrName name) {
     obj->attr().set(__name__, VAR(name.sv()));
     // we do not allow override in order to avoid memory leak
     // it is because Module objects are not garbage collected
-    if(_modules.contains(name)) UNREACHABLE();
+    if(_modules.contains(name)) FATAL_ERROR();
     _modules.set(name, obj);
     return obj;
 }
@@ -639,7 +639,7 @@ inline void VM::init_builtin_types(){
 
     tp_int = _new_type_object("int");
     tp_float = _new_type_object("float");
-    if(tp_int.index != kTpIntIndex || tp_float.index != kTpFloatIndex) UNREACHABLE();
+    if(tp_int.index != kTpIntIndex || tp_float.index != kTpFloatIndex) FATAL_ERROR();
 
     tp_bool = _new_type_object("bool");
     tp_str = _new_type_object("str");