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