mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-21 12:00:18 +00:00
up
This commit is contained in:
parent
e3eebfa35c
commit
80e49a677e
@ -13,7 +13,7 @@ inline PyObject* VM::_run_top_frame(){
|
|||||||
|
|
||||||
while(true){
|
while(true){
|
||||||
#if DEBUG_EXTRA_CHECK
|
#if DEBUG_EXTRA_CHECK
|
||||||
if(frame->id < base_id) UNREACHABLE();
|
if(frame->id < base_id) FATAL_ERROR();
|
||||||
#endif
|
#endif
|
||||||
try{
|
try{
|
||||||
if(need_raise){ need_raise = false; _raise(); }
|
if(need_raise){ need_raise = false; _raise(); }
|
||||||
@ -498,7 +498,7 @@ __NEXT_STEP:;
|
|||||||
#if DEBUG_EXTRA_CHECK
|
#if DEBUG_EXTRA_CHECK
|
||||||
default: throw std::runtime_error(fmt(OP_NAMES[byte.op], " is not implemented"));
|
default: throw std::runtime_error(fmt(OP_NAMES[byte.op], " is not implemented"));
|
||||||
#else
|
#else
|
||||||
default: std::unreachable();
|
default: UNREACHABLE();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -312,7 +312,7 @@ struct Pointer{
|
|||||||
CASE(double, f64);
|
CASE(double, f64);
|
||||||
CASE(bool, bool);
|
CASE(bool, bool);
|
||||||
#undef CASE
|
#undef CASE
|
||||||
default: UNREACHABLE();
|
default: FATAL_ERROR();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,8 +51,10 @@
|
|||||||
|
|
||||||
#if _MSC_VER
|
#if _MSC_VER
|
||||||
#define PK_ENABLE_COMPUTED_GOTO 0
|
#define PK_ENABLE_COMPUTED_GOTO 0
|
||||||
|
#define UNREACHABLE() __assume(0)
|
||||||
#else
|
#else
|
||||||
#define PK_ENABLE_COMPUTED_GOTO 1
|
#define PK_ENABLE_COMPUTED_GOTO 1
|
||||||
|
#define UNREACHABLE() __builtin_unreachable()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__EMSCRIPTEN__) || defined(__arm__) || defined(__i386__)
|
#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; })
|
#define CPP_NOT_IMPLEMENTED() ([](VM* vm, Args& args) { vm->NotImplementedError(); return vm->None; })
|
||||||
|
|
||||||
#ifdef POCKETPY_H
|
#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
|
#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
|
#endif
|
||||||
|
|
||||||
inline const float kLocalsLoadFactor = 0.67f;
|
inline const float kLocalsLoadFactor = 0.67f;
|
||||||
|
@ -267,7 +267,7 @@ class Compiler {
|
|||||||
case TK("*"):
|
case TK("*"):
|
||||||
ctx()->s_expr.push(make_expr<StarredExpr>(ctx()->s_expr.popx()));
|
ctx()->s_expr.push(make_expr<StarredExpr>(ctx()->s_expr.popx()));
|
||||||
break;
|
break;
|
||||||
default: UNREACHABLE();
|
default: FATAL_ERROR();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,7 +464,7 @@ __SUBSCR_END:
|
|||||||
if(is_slice){
|
if(is_slice){
|
||||||
e->b = std::move(slice);
|
e->b = std::move(slice);
|
||||||
}else{
|
}else{
|
||||||
if(state != 1) UNREACHABLE();
|
if(state != 1) FATAL_ERROR();
|
||||||
e->b = std::move(slice->start);
|
e->b = std::move(slice->start);
|
||||||
}
|
}
|
||||||
ctx()->s_expr.push(std::move(e));
|
ctx()->s_expr.push(std::move(e));
|
||||||
@ -936,7 +936,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
CodeObject_ compile(){
|
CodeObject_ compile(){
|
||||||
if(used) UNREACHABLE();
|
if(used) FATAL_ERROR();
|
||||||
used = true;
|
used = true;
|
||||||
|
|
||||||
tokens = lexer->run();
|
tokens = lexer->run();
|
||||||
|
16
src/expr.h
16
src/expr.h
@ -55,7 +55,7 @@ struct CodeEmitContext{
|
|||||||
if(co->blocks[curr_block_i].type == FOR_LOOP) for_loop_depth--;
|
if(co->blocks[curr_block_i].type == FOR_LOOP) for_loop_depth--;
|
||||||
co->blocks[curr_block_i].end = co->codes.size();
|
co->blocks[curr_block_i].end = co->codes.size();
|
||||||
curr_block_i = co->blocks[curr_block_i].parent;
|
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
|
// clear the expression stack and generate bytecode
|
||||||
@ -137,7 +137,7 @@ struct NameExpr: Expr{
|
|||||||
case NAME_GLOBAL:
|
case NAME_GLOBAL:
|
||||||
ctx->emit(OP_DELETE_GLOBAL, index, line);
|
ctx->emit(OP_DELETE_GLOBAL, index, line);
|
||||||
break;
|
break;
|
||||||
default: UNREACHABLE(); break;
|
default: FATAL_ERROR(); break;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -155,7 +155,7 @@ struct NameExpr: Expr{
|
|||||||
case NAME_GLOBAL:
|
case NAME_GLOBAL:
|
||||||
ctx->emit(OP_STORE_GLOBAL, index, line);
|
ctx->emit(OP_STORE_GLOBAL, index, line);
|
||||||
break;
|
break;
|
||||||
default: UNREACHABLE(); break;
|
default: FATAL_ERROR(); break;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -229,7 +229,7 @@ struct Literal0Expr: Expr{
|
|||||||
case TK("True"): ctx->emit(OP_LOAD_TRUE, BC_NOARG, line); break;
|
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("False"): ctx->emit(OP_LOAD_FALSE, BC_NOARG, line); break;
|
||||||
case TK("..."): ctx->emit(OP_LOAD_ELLIPSIS, 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();
|
return s.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
UNREACHABLE();
|
FATAL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* to_object(CodeEmitContext* ctx){
|
PyObject* to_object(CodeEmitContext* ctx){
|
||||||
@ -274,7 +274,7 @@ struct LiteralExpr: Expr{
|
|||||||
|
|
||||||
void emit(CodeEmitContext* ctx) override {
|
void emit(CodeEmitContext* ctx) override {
|
||||||
PyObject* obj = to_object(ctx);
|
PyObject* obj = to_object(ctx);
|
||||||
if(obj == nullptr) UNREACHABLE();
|
if(obj == nullptr) FATAL_ERROR();
|
||||||
int index = ctx->add_const(obj);
|
int index = ctx->add_const(obj);
|
||||||
ctx->emit(OP_LOAD_CONST, index, line);
|
ctx->emit(OP_LOAD_CONST, index, line);
|
||||||
}
|
}
|
||||||
@ -448,7 +448,7 @@ struct CompExpr: Expr{
|
|||||||
ctx->emit(OP_FOR_ITER, BC_NOARG, BC_KEEPLINE);
|
ctx->emit(OP_FOR_ITER, BC_NOARG, BC_KEEPLINE);
|
||||||
bool ok = vars->emit_store(ctx);
|
bool ok = vars->emit_store(ctx);
|
||||||
// this error occurs in `vars` instead of this line, but...nevermind
|
// 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){
|
if(cond){
|
||||||
cond->emit(ctx);
|
cond->emit(ctx);
|
||||||
int patch = ctx->emit(OP_POP_JUMP_IF_FALSE, BC_NOARG, BC_KEEPLINE);
|
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_AND, BC_NOARG, line); break;
|
||||||
case TK("|"): ctx->emit(OP_BITWISE_OR, 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;
|
case TK("^"): ctx->emit(OP_BITWISE_XOR, BC_NOARG, line); break;
|
||||||
default: UNREACHABLE();
|
default: FATAL_ERROR();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
2
src/gc.h
2
src/gc.h
@ -101,7 +101,7 @@ struct ManagedHeap{
|
|||||||
}
|
}
|
||||||
|
|
||||||
int collect(){
|
int collect(){
|
||||||
if(_gc_lock_counter > 0) UNREACHABLE();
|
if(_gc_lock_counter > 0) FATAL_ERROR();
|
||||||
mark();
|
mark();
|
||||||
int freed = sweep();
|
int freed = sweep();
|
||||||
return freed;
|
return freed;
|
||||||
|
@ -38,7 +38,7 @@ constexpr TokenIndex TK(const char token[]) {
|
|||||||
while(*i && *j && *i == *j) { i++; j++;}
|
while(*i && *j && *i == *j) { i++; j++;}
|
||||||
if(*i == *j) return k;
|
if(*i == *j) return k;
|
||||||
}
|
}
|
||||||
UNREACHABLE();
|
FATAL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TK_STR(t) kTokens[t]
|
#define TK_STR(t) kTokens[t]
|
||||||
@ -344,7 +344,7 @@ struct Lexer {
|
|||||||
} else {
|
} else {
|
||||||
add_token(TK("@num"), S_TO_INT(m[0], &size, base));
|
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& _){
|
}catch(std::exception& _){
|
||||||
SyntaxError("invalid number literal");
|
SyntaxError("invalid number literal");
|
||||||
@ -448,7 +448,7 @@ struct Lexer {
|
|||||||
case 2: SyntaxError("invalid utf8 sequence: " + std::string(1, c));
|
case 2: SyntaxError("invalid utf8 sequence: " + std::string(1, c));
|
||||||
case 3: SyntaxError("@id contains invalid char"); break;
|
case 3: SyntaxError("@id contains invalid char"); break;
|
||||||
case 4: SyntaxError("invalid JSON token"); break;
|
case 4: SyntaxError("invalid JSON token"); break;
|
||||||
default: UNREACHABLE();
|
default: FATAL_ERROR();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -494,7 +494,7 @@ struct Lexer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Token> run() {
|
std::vector<Token> run() {
|
||||||
if(used) UNREACHABLE();
|
if(used) FATAL_ERROR();
|
||||||
used = true;
|
used = true;
|
||||||
while (lex_one_token());
|
while (lex_one_token());
|
||||||
return std::move(nexts);
|
return std::move(nexts);
|
||||||
|
@ -119,7 +119,7 @@ while(!_items[i].first.empty()) { \
|
|||||||
if(old_items[i].first.empty()) continue;
|
if(old_items[i].first.empty()) continue;
|
||||||
bool ok; uint16_t j;
|
bool ok; uint16_t j;
|
||||||
HASH_PROBE(old_items[i].first, ok, j);
|
HASH_PROBE(old_items[i].first, ok, j);
|
||||||
if(ok) UNREACHABLE();
|
if(ok) FATAL_ERROR();
|
||||||
_items[j] = old_items[i];
|
_items[j] = old_items[i];
|
||||||
}
|
}
|
||||||
pool128.dealloc(old_items);
|
pool128.dealloc(old_items);
|
||||||
|
@ -183,7 +183,7 @@ inline bool is_type(PyObject* obj, Type type) {
|
|||||||
} \
|
} \
|
||||||
static PyObject* register_class(VM* vm, PyObject* mod) { \
|
static PyObject* register_class(VM* vm, PyObject* mod) { \
|
||||||
PyObject* type = vm->new_type_object(mod, #name, vm->tp_object); \
|
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); \
|
T::_register(vm, mod, type); \
|
||||||
type->attr()._try_perfect_rehash(); \
|
type->attr()._try_perfect_rehash(); \
|
||||||
return type; \
|
return type; \
|
||||||
|
@ -978,7 +978,7 @@ extern "C" {
|
|||||||
case 'N': f_None(packet); return vm->None;
|
case 'N': f_None(packet); return vm->None;
|
||||||
}
|
}
|
||||||
free(packet);
|
free(packet);
|
||||||
UNREACHABLE();
|
FATAL_ERROR();
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
return strdup(f_header.c_str());
|
return strdup(f_header.c_str());
|
||||||
|
6
src/vm.h
6
src/vm.h
@ -102,7 +102,7 @@ public:
|
|||||||
|
|
||||||
FrameId top_frame() {
|
FrameId top_frame() {
|
||||||
#if DEBUG_EXTRA_CHECK
|
#if DEBUG_EXTRA_CHECK
|
||||||
if(callstack.empty()) UNREACHABLE();
|
if(callstack.empty()) FATAL_ERROR();
|
||||||
#endif
|
#endif
|
||||||
return FrameId(&callstack.data(), callstack.size()-1);
|
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()));
|
obj->attr().set(__name__, VAR(name.sv()));
|
||||||
// we do not allow override in order to avoid memory leak
|
// we do not allow override in order to avoid memory leak
|
||||||
// it is because Module objects are not garbage collected
|
// it is because Module objects are not garbage collected
|
||||||
if(_modules.contains(name)) UNREACHABLE();
|
if(_modules.contains(name)) FATAL_ERROR();
|
||||||
_modules.set(name, obj);
|
_modules.set(name, obj);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
@ -639,7 +639,7 @@ inline void VM::init_builtin_types(){
|
|||||||
|
|
||||||
tp_int = _new_type_object("int");
|
tp_int = _new_type_object("int");
|
||||||
tp_float = _new_type_object("float");
|
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_bool = _new_type_object("bool");
|
||||||
tp_str = _new_type_object("str");
|
tp_str = _new_type_object("str");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user