mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
some refactor
This commit is contained in:
parent
a99b271a4e
commit
b703abbbb2
@ -125,7 +125,6 @@ struct Type {
|
||||
|
||||
struct PyObject;
|
||||
#define PK_BITS(p) (reinterpret_cast<i64>(p))
|
||||
#define PK_SMALL_INT(val) (reinterpret_cast<PyObject*>(val << 2 | 0b10))
|
||||
|
||||
// is_pod<> for c++17 and c++20
|
||||
template<typename T>
|
||||
|
@ -14,23 +14,7 @@ OPCODE(LOAD_NONE)
|
||||
OPCODE(LOAD_TRUE)
|
||||
OPCODE(LOAD_FALSE)
|
||||
/**************************/
|
||||
OPCODE(LOAD_INT_0)
|
||||
OPCODE(LOAD_INT_1)
|
||||
OPCODE(LOAD_INT_2)
|
||||
OPCODE(LOAD_INT_3)
|
||||
OPCODE(LOAD_INT_4)
|
||||
OPCODE(LOAD_INT_5)
|
||||
OPCODE(LOAD_INT_6)
|
||||
OPCODE(LOAD_INT_7)
|
||||
OPCODE(LOAD_INT_8)
|
||||
OPCODE(LOAD_INT_9)
|
||||
OPCODE(LOAD_INT_10)
|
||||
OPCODE(LOAD_INT_11)
|
||||
OPCODE(LOAD_INT_12)
|
||||
OPCODE(LOAD_INT_13)
|
||||
OPCODE(LOAD_INT_14)
|
||||
OPCODE(LOAD_INT_15)
|
||||
OPCODE(LOAD_INT_16)
|
||||
OPCODE(LOAD_SMALL_INT)
|
||||
/**************************/
|
||||
OPCODE(LOAD_ELLIPSIS)
|
||||
OPCODE(LOAD_FUNCTION)
|
||||
@ -44,12 +28,14 @@ OPCODE(LOAD_ATTR)
|
||||
OPCODE(LOAD_CLASS_GLOBAL)
|
||||
OPCODE(LOAD_METHOD)
|
||||
OPCODE(LOAD_SUBSCR)
|
||||
OPCODE(LOAD_SUBSCR_FAST)
|
||||
|
||||
OPCODE(STORE_FAST)
|
||||
OPCODE(STORE_NAME)
|
||||
OPCODE(STORE_GLOBAL)
|
||||
OPCODE(STORE_ATTR)
|
||||
OPCODE(STORE_SUBSCR)
|
||||
OPCODE(STORE_SUBSCR_FAST)
|
||||
|
||||
OPCODE(DELETE_FAST)
|
||||
OPCODE(DELETE_NAME)
|
||||
|
@ -10,7 +10,7 @@ namespace pkpy{
|
||||
|
||||
#define PREDICT_INT_DIV_OP(op) \
|
||||
if(is_small_int(_0) && is_small_int(_1)){ \
|
||||
if(_1 == PK_SMALL_INT(0)) ZeroDivisionError(); \
|
||||
if(_1 == (PyObject*)0b10) ZeroDivisionError(); \
|
||||
TOP() = VAR((PK_BITS(_0)>>2) op (PK_BITS(_1)>>2)); \
|
||||
DISPATCH() \
|
||||
}
|
||||
@ -112,30 +112,13 @@ __NEXT_STEP:;
|
||||
} DISPATCH();
|
||||
/*****************************************/
|
||||
TARGET(LOAD_CONST)
|
||||
if(heap._should_auto_collect()) heap._auto_collect();
|
||||
PUSH(co->consts[byte.arg]);
|
||||
DISPATCH();
|
||||
TARGET(LOAD_NONE) PUSH(None); DISPATCH();
|
||||
TARGET(LOAD_TRUE) PUSH(True); DISPATCH();
|
||||
TARGET(LOAD_FALSE) PUSH(False); DISPATCH();
|
||||
/*****************************************/
|
||||
TARGET(LOAD_INT_0) PUSH(PK_SMALL_INT(0)); DISPATCH();
|
||||
TARGET(LOAD_INT_1) PUSH(PK_SMALL_INT(1)); DISPATCH();
|
||||
TARGET(LOAD_INT_2) PUSH(PK_SMALL_INT(2)); DISPATCH();
|
||||
TARGET(LOAD_INT_3) PUSH(PK_SMALL_INT(3)); DISPATCH();
|
||||
TARGET(LOAD_INT_4) PUSH(PK_SMALL_INT(4)); DISPATCH();
|
||||
TARGET(LOAD_INT_5) PUSH(PK_SMALL_INT(5)); DISPATCH();
|
||||
TARGET(LOAD_INT_6) PUSH(PK_SMALL_INT(6)); DISPATCH();
|
||||
TARGET(LOAD_INT_7) PUSH(PK_SMALL_INT(7)); DISPATCH();
|
||||
TARGET(LOAD_INT_8) PUSH(PK_SMALL_INT(8)); DISPATCH();
|
||||
TARGET(LOAD_INT_9) PUSH(PK_SMALL_INT(9)); DISPATCH();
|
||||
TARGET(LOAD_INT_10) PUSH(PK_SMALL_INT(10)); DISPATCH();
|
||||
TARGET(LOAD_INT_11) PUSH(PK_SMALL_INT(11)); DISPATCH();
|
||||
TARGET(LOAD_INT_12) PUSH(PK_SMALL_INT(12)); DISPATCH();
|
||||
TARGET(LOAD_INT_13) PUSH(PK_SMALL_INT(13)); DISPATCH();
|
||||
TARGET(LOAD_INT_14) PUSH(PK_SMALL_INT(14)); DISPATCH();
|
||||
TARGET(LOAD_INT_15) PUSH(PK_SMALL_INT(15)); DISPATCH();
|
||||
TARGET(LOAD_INT_16) PUSH(PK_SMALL_INT(16)); DISPATCH();
|
||||
TARGET(LOAD_SMALL_INT) PUSH((PyObject*)(uintptr_t)byte.arg); DISPATCH();
|
||||
/*****************************************/
|
||||
TARGET(LOAD_ELLIPSIS) PUSH(Ellipsis); DISPATCH();
|
||||
TARGET(LOAD_FUNCTION) {
|
||||
@ -153,7 +136,6 @@ __NEXT_STEP:;
|
||||
TARGET(LOAD_NULL) PUSH(PY_NULL); DISPATCH();
|
||||
/*****************************************/
|
||||
TARGET(LOAD_FAST) {
|
||||
if(heap._should_auto_collect()) heap._auto_collect();
|
||||
PyObject* _0 = frame->_locals[byte.arg];
|
||||
if(_0 == PY_NULL) vm->UnboundLocalError(co->varnames[byte.arg]);
|
||||
PUSH(_0);
|
||||
@ -175,7 +157,6 @@ __NEXT_STEP:;
|
||||
vm->NameError(_name);
|
||||
} DISPATCH();
|
||||
TARGET(LOAD_NONLOCAL) {
|
||||
if(heap._should_auto_collect()) heap._auto_collect();
|
||||
StrName _name(byte.arg);
|
||||
PyObject* _0 = frame->f_closure_try_get(_name);
|
||||
if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
|
||||
@ -186,7 +167,6 @@ __NEXT_STEP:;
|
||||
vm->NameError(_name);
|
||||
} DISPATCH();
|
||||
TARGET(LOAD_GLOBAL){
|
||||
if(heap._should_auto_collect()) heap._auto_collect();
|
||||
StrName _name(byte.arg);
|
||||
PyObject* _0 = frame->f_globals().try_get_likely_found(_name);
|
||||
if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
|
||||
@ -224,6 +204,17 @@ __NEXT_STEP:;
|
||||
TOP() = call_method(_0, __getitem__, _1);
|
||||
}
|
||||
} DISPATCH();
|
||||
TARGET(LOAD_SUBSCR_FAST){
|
||||
PyObject* _1 = frame->_locals[byte.arg];
|
||||
if(_1 == PY_NULL) vm->UnboundLocalError(co->varnames[byte.arg]);
|
||||
PyObject* _0 = TOP(); // a
|
||||
auto _ti = _inst_type_info(_0);
|
||||
if(_ti->m__getitem__){
|
||||
TOP() = _ti->m__getitem__(this, _0, _1);
|
||||
}else{
|
||||
TOP() = call_method(_0, __getitem__, _1);
|
||||
}
|
||||
} DISPATCH();
|
||||
TARGET(STORE_FAST)
|
||||
frame->_locals[byte.arg] = POPX();
|
||||
DISPATCH();
|
||||
@ -258,6 +249,18 @@ __NEXT_STEP:;
|
||||
call_method(_1, __setitem__, _2, _0);
|
||||
}
|
||||
}DISPATCH();
|
||||
TARGET(STORE_SUBSCR_FAST){
|
||||
PyObject* _2 = frame->_locals[byte.arg]; // b
|
||||
if(_2 == PY_NULL) vm->UnboundLocalError(co->varnames[byte.arg]);
|
||||
PyObject* _1 = POPX(); // a
|
||||
PyObject* _0 = POPX(); // val
|
||||
auto _ti = _inst_type_info(_1);
|
||||
if(_ti->m__setitem__){
|
||||
_ti->m__setitem__(this, _1, _2, _0);
|
||||
}else{
|
||||
call_method(_1, __setitem__, _2, _0);
|
||||
}
|
||||
}DISPATCH();
|
||||
TARGET(DELETE_FAST){
|
||||
PyObject* _0 = frame->_locals[byte.arg];
|
||||
if(_0 == PY_NULL) vm->UnboundLocalError(co->varnames[byte.arg]);
|
||||
@ -620,6 +623,7 @@ __NEXT_STEP:;
|
||||
TOP() = py_repr(TOP());
|
||||
DISPATCH();
|
||||
TARGET(CALL){
|
||||
if(heap._should_auto_collect()) heap._auto_collect();
|
||||
PyObject* _0 = vectorcall(
|
||||
byte.arg & 0xFF, // ARGC
|
||||
(byte.arg>>8) & 0xFF, // KWARGC
|
||||
@ -629,6 +633,7 @@ __NEXT_STEP:;
|
||||
PUSH(_0);
|
||||
} DISPATCH();
|
||||
TARGET(CALL_TP){
|
||||
if(heap._should_auto_collect()) heap._auto_collect();
|
||||
PyObject* _0;
|
||||
PyObject* _1;
|
||||
PyObject* _2;
|
||||
@ -772,14 +777,25 @@ __NEXT_STEP:;
|
||||
} DISPATCH();
|
||||
/*****************************************/
|
||||
TARGET(UNPACK_SEQUENCE){
|
||||
auto _lock = heap.gc_scope_lock(); // lock the gc via RAII!!
|
||||
PyObject* _0 = py_iter(POPX());
|
||||
for(int i=0; i<byte.arg; i++){
|
||||
PyObject* _1 = py_next(_0);
|
||||
if(_1 == StopIteration) ValueError("not enough values to unpack");
|
||||
PUSH(_1);
|
||||
PyObject* _0 = POPX();
|
||||
if(is_type(_0, VM::tp_tuple)){
|
||||
// fast path for tuple
|
||||
Tuple& tuple = PK_OBJ_GET(Tuple, _0);
|
||||
if(tuple.size() == byte.arg){
|
||||
for(PyObject* obj: tuple) PUSH(obj);
|
||||
}else{
|
||||
ValueError(_S("expected ", (int)byte.arg, " values to unpack, got ", (int)tuple.size()));
|
||||
}
|
||||
}else{
|
||||
auto _lock = heap.gc_scope_lock(); // lock the gc via RAII!!
|
||||
_0 = py_iter(_0);
|
||||
for(int i=0; i<byte.arg; i++){
|
||||
PyObject* _1 = py_next(_0);
|
||||
if(_1 == StopIteration) ValueError("not enough values to unpack");
|
||||
PUSH(_1);
|
||||
}
|
||||
if(py_next(_0) != StopIteration) ValueError("too many values to unpack");
|
||||
}
|
||||
if(py_next(_0) != StopIteration) ValueError("too many values to unpack");
|
||||
} DISPATCH();
|
||||
TARGET(UNPACK_EX) {
|
||||
auto _lock = heap.gc_scope_lock(); // lock the gc via RAII!!
|
||||
|
37
src/expr.cpp
37
src/expr.cpp
@ -86,9 +86,9 @@ namespace pkpy{
|
||||
}
|
||||
|
||||
int CodeEmitContext::emit_int(i64 value, int line){
|
||||
if(value >= 0 && value <= 16){
|
||||
uint8_t op = OP_LOAD_INT_0 + (uint8_t)value;
|
||||
return emit_((Opcode)op, BC_NOARG, line);
|
||||
if(value >= 0 && value < 1024){
|
||||
value = (value << 2) | 0b10;
|
||||
return emit_(OP_LOAD_SMALL_INT, (uint16_t)value, line);
|
||||
}else{
|
||||
return emit_(OP_LOAD_CONST, add_const(VAR(value)), line);
|
||||
}
|
||||
@ -359,8 +359,7 @@ namespace pkpy{
|
||||
Bytecode& prev = ctx->co->codes.back();
|
||||
if(prev.op == OP_BUILD_TUPLE && prev.arg == items.size()){
|
||||
// build tuple and unpack it is meaningless
|
||||
prev.op = OP_NO_OP;
|
||||
prev.arg = BC_NOARG;
|
||||
ctx->revert_last_emit_();
|
||||
}else{
|
||||
ctx->emit_(OP_UNPACK_SEQUENCE, items.size(), line);
|
||||
}
|
||||
@ -537,7 +536,26 @@ namespace pkpy{
|
||||
void SubscrExpr::emit_(CodeEmitContext* ctx){
|
||||
a->emit_(ctx);
|
||||
b->emit_(ctx);
|
||||
ctx->emit_(OP_LOAD_SUBSCR, BC_NOARG, line);
|
||||
if(b->is_name() && ctx->co->codes.back().op == OP_LOAD_FAST){
|
||||
auto arg = ctx->co->codes.back().arg;
|
||||
ctx->revert_last_emit_();
|
||||
ctx->emit_(OP_LOAD_SUBSCR_FAST, arg, line);
|
||||
}else{
|
||||
ctx->emit_(OP_LOAD_SUBSCR, BC_NOARG, line);
|
||||
}
|
||||
}
|
||||
|
||||
bool SubscrExpr::emit_store(CodeEmitContext* ctx){
|
||||
a->emit_(ctx);
|
||||
b->emit_(ctx);
|
||||
if(b->is_name() && ctx->co->codes.back().op == OP_LOAD_FAST){
|
||||
auto arg = ctx->co->codes.back().arg;
|
||||
ctx->revert_last_emit_();
|
||||
ctx->emit_(OP_STORE_SUBSCR_FAST, arg, line);
|
||||
}else{
|
||||
ctx->emit_(OP_STORE_SUBSCR, BC_NOARG, line);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SubscrExpr::emit_del(CodeEmitContext* ctx){
|
||||
@ -547,13 +565,6 @@ namespace pkpy{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SubscrExpr::emit_store(CodeEmitContext* ctx){
|
||||
a->emit_(ctx);
|
||||
b->emit_(ctx);
|
||||
ctx->emit_(OP_STORE_SUBSCR, BC_NOARG, line);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AttribExpr::emit_(CodeEmitContext* ctx){
|
||||
a->emit_(ctx);
|
||||
ctx->emit_(OP_LOAD_ATTR, b.index, line);
|
||||
|
@ -577,12 +577,15 @@ static std::string _opcode_argstr(VM* vm, Bytecode byte, const CodeObject* co){
|
||||
case OP_DELETE_GLOBAL: case OP_INC_GLOBAL: case OP_DEC_GLOBAL: case OP_STORE_CLASS_ATTR: case OP_FOR_ITER_STORE_GLOBAL:
|
||||
argStr += _S(" (", StrName(byte.arg).sv(), ")").sv();
|
||||
break;
|
||||
case OP_LOAD_FAST: case OP_STORE_FAST: case OP_DELETE_FAST: case OP_INC_FAST: case OP_DEC_FAST: case OP_FOR_ITER_STORE_FAST:
|
||||
case OP_LOAD_FAST: case OP_STORE_FAST: case OP_DELETE_FAST: case OP_INC_FAST: case OP_DEC_FAST:
|
||||
case OP_FOR_ITER_STORE_FAST: case OP_LOAD_SUBSCR_FAST: case OP_STORE_SUBSCR_FAST:
|
||||
argStr += _S(" (", co->varnames[byte.arg].sv(), ")").sv();
|
||||
break;
|
||||
case OP_LOAD_FUNCTION:
|
||||
argStr += _S(" (", co->func_decls[byte.arg]->code->name, ")").sv();
|
||||
break;
|
||||
case OP_LOAD_SMALL_INT:
|
||||
argStr += _S(" (", (int)(byte.arg >> 2), ")").sv();
|
||||
}
|
||||
return argStr;
|
||||
}
|
||||
|
@ -129,3 +129,6 @@ try:
|
||||
exit(1)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
a, b = [1, 2]
|
||||
assert a == 1 and b == 2
|
||||
|
Loading…
x
Reference in New Issue
Block a user