This commit is contained in:
blueloveTH 2023-05-20 14:15:17 +08:00
parent d61bb3f16e
commit 8c85881d14
4 changed files with 26 additions and 13 deletions

View File

@ -10,4 +10,5 @@ These are the undefined behaviours of pkpy. The behaviour of pkpy is undefined i
3. Use goto statement to jump out of a context block. 3. Use goto statement to jump out of a context block.
4. Type `T`'s `__new__` returns an object that is not an instance of `T`. 4. Type `T`'s `__new__` returns an object that is not an instance of `T`.
5. Call `__new__` with a type that is not a subclass of `type`. 5. Call `__new__` with a type that is not a subclass of `type`.
6. `__eq__`, `__ne__` or `__contains__`, etc.. returns a value that is not a boolean. 6. `__eq__`, `__ne__` or `__contains__`, etc.. returns a value that is not a boolean.
7. Division by zero.

View File

@ -271,6 +271,14 @@ __NEXT_STEP:;
PUSH(VAR(ss.str())); PUSH(VAR(ss.str()));
} DISPATCH(); } DISPATCH();
/*****************************************/ /*****************************************/
#define PREDICT_INT_OP(op) \
if(is_both_int(TOP(), SECOND())){ \
_1 = POPX(); \
_0 = TOP(); \
TOP() = VAR(_CAST(i64, _0) op _CAST(i64, _1)); \
DISPATCH(); \
}
#define BINARY_OP_SPECIAL(func) \ #define BINARY_OP_SPECIAL(func) \
_1 = POPX(); \ _1 = POPX(); \
_0 = TOP(); \ _0 = TOP(); \
@ -282,30 +290,35 @@ __NEXT_STEP:;
} }
TARGET(BINARY_TRUEDIV) TARGET(BINARY_TRUEDIV)
if(is_tagged(SECOND())){
f64 lhs = num_to_float(SECOND());
f64 rhs = num_to_float(TOP());
POP();
TOP() = VAR(lhs / rhs);
DISPATCH();
}
BINARY_OP_SPECIAL(__truediv__); BINARY_OP_SPECIAL(__truediv__);
DISPATCH(); DISPATCH();
TARGET(BINARY_POW) TARGET(BINARY_POW)
BINARY_OP_SPECIAL(__pow__); BINARY_OP_SPECIAL(__pow__);
DISPATCH(); DISPATCH();
TARGET(BINARY_ADD) TARGET(BINARY_ADD)
if(is_both_int(TOP(), SECOND())){ PREDICT_INT_OP(+);
_1 = POPX();
_0 = TOP();
TOP() = VAR(_CAST(i64, _0) + _CAST(i64, _1));
DISPATCH();
}
BINARY_OP_SPECIAL(__add__); BINARY_OP_SPECIAL(__add__);
DISPATCH() DISPATCH()
TARGET(BINARY_SUB) TARGET(BINARY_SUB)
PREDICT_INT_OP(-);
BINARY_OP_SPECIAL(__sub__); BINARY_OP_SPECIAL(__sub__);
DISPATCH() DISPATCH()
TARGET(BINARY_MUL) TARGET(BINARY_MUL)
BINARY_OP_SPECIAL(__mul__); BINARY_OP_SPECIAL(__mul__);
DISPATCH() DISPATCH()
TARGET(BINARY_FLOORDIV) TARGET(BINARY_FLOORDIV)
PREDICT_INT_OP(/);
BINARY_OP_SPECIAL(__floordiv__); BINARY_OP_SPECIAL(__floordiv__);
DISPATCH() DISPATCH()
TARGET(BINARY_MOD) TARGET(BINARY_MOD)
PREDICT_INT_OP(%);
BINARY_OP_SPECIAL(__mod__); BINARY_OP_SPECIAL(__mod__);
DISPATCH() DISPATCH()
TARGET(COMPARE_LT) TARGET(COMPARE_LT)
@ -331,18 +344,23 @@ __NEXT_STEP:;
BINARY_OP_SPECIAL(__ge__); BINARY_OP_SPECIAL(__ge__);
DISPATCH() DISPATCH()
TARGET(BITWISE_LSHIFT) TARGET(BITWISE_LSHIFT)
PREDICT_INT_OP(<<);
BINARY_OP_SPECIAL(__lshift__); BINARY_OP_SPECIAL(__lshift__);
DISPATCH() DISPATCH()
TARGET(BITWISE_RSHIFT) TARGET(BITWISE_RSHIFT)
PREDICT_INT_OP(>>);
BINARY_OP_SPECIAL(__rshift__); BINARY_OP_SPECIAL(__rshift__);
DISPATCH() DISPATCH()
TARGET(BITWISE_AND) TARGET(BITWISE_AND)
PREDICT_INT_OP(&);
BINARY_OP_SPECIAL(__and__); BINARY_OP_SPECIAL(__and__);
DISPATCH() DISPATCH()
TARGET(BITWISE_OR) TARGET(BITWISE_OR)
PREDICT_INT_OP(|);
BINARY_OP_SPECIAL(__or__); BINARY_OP_SPECIAL(__or__);
DISPATCH() DISPATCH()
TARGET(BITWISE_XOR) TARGET(BITWISE_XOR)
PREDICT_INT_OP(^);
BINARY_OP_SPECIAL(__xor__); BINARY_OP_SPECIAL(__xor__);
DISPATCH() DISPATCH()
TARGET(BINARY_MATMUL) TARGET(BINARY_MATMUL)

View File

@ -107,7 +107,6 @@ inline void init_builtins(VM* _vm) {
_vm->bind_builtin_func<2>("divmod", [](VM* vm, ArgsView args) { _vm->bind_builtin_func<2>("divmod", [](VM* vm, ArgsView args) {
i64 lhs = CAST(i64, args[0]); i64 lhs = CAST(i64, args[0]);
i64 rhs = CAST(i64, args[1]); i64 rhs = CAST(i64, args[1]);
if(rhs == 0) vm->ZeroDivisionError();
return VAR(Tuple({VAR(lhs/rhs), VAR(lhs%rhs)})); return VAR(Tuple({VAR(lhs/rhs), VAR(lhs%rhs)}));
}); });
@ -233,13 +232,11 @@ inline void init_builtins(VM* _vm) {
_vm->bind__truediv__(_vm->tp_float, [](VM* vm, PyObject* lhs, PyObject* rhs) { _vm->bind__truediv__(_vm->tp_float, [](VM* vm, PyObject* lhs, PyObject* rhs) {
f64 value = VAR_F(rhs); f64 value = VAR_F(rhs);
if (value == 0) vm->ZeroDivisionError();
return VAR(_CAST(f64, lhs) / value); return VAR(_CAST(f64, lhs) / value);
}); });
_vm->bind__truediv__(_vm->tp_int, [](VM* vm, PyObject* lhs, PyObject* rhs) { _vm->bind__truediv__(_vm->tp_int, [](VM* vm, PyObject* lhs, PyObject* rhs) {
f64 value = VAR_F(rhs); f64 value = VAR_F(rhs);
if (value == 0) vm->ZeroDivisionError();
return VAR(_CAST(i64, lhs) / value); return VAR(_CAST(i64, lhs) / value);
}); });
@ -287,13 +284,11 @@ inline void init_builtins(VM* _vm) {
_vm->bind__floordiv__(_vm->tp_int, [](VM* vm, PyObject* lhs_, PyObject* rhs_) { _vm->bind__floordiv__(_vm->tp_int, [](VM* vm, PyObject* lhs_, PyObject* rhs_) {
i64 rhs = CAST(i64, rhs_); i64 rhs = CAST(i64, rhs_);
if(rhs == 0) vm->ZeroDivisionError();
return VAR(_CAST(i64, lhs_) / rhs); return VAR(_CAST(i64, lhs_) / rhs);
}); });
_vm->bind__mod__(_vm->tp_int, [](VM* vm, PyObject* lhs_, PyObject* rhs_) { _vm->bind__mod__(_vm->tp_int, [](VM* vm, PyObject* lhs_, PyObject* rhs_) {
i64 rhs = CAST(i64, rhs_); i64 rhs = CAST(i64, rhs_);
if(rhs == 0) vm->ZeroDivisionError();
return VAR(_CAST(i64, lhs_) % rhs); return VAR(_CAST(i64, lhs_) % rhs);
}); });

View File

@ -518,7 +518,6 @@ public:
void IOError(const Str& msg) { _error("IOError", msg); } void IOError(const Str& msg) { _error("IOError", msg); }
void NotImplementedError(){ _error("NotImplementedError", ""); } void NotImplementedError(){ _error("NotImplementedError", ""); }
void TypeError(const Str& msg){ _error("TypeError", msg); } void TypeError(const Str& msg){ _error("TypeError", msg); }
void ZeroDivisionError(){ _error("ZeroDivisionError", "division by zero"); }
void IndexError(const Str& msg){ _error("IndexError", msg); } void IndexError(const Str& msg){ _error("IndexError", msg); }
void ValueError(const Str& msg){ _error("ValueError", msg); } void ValueError(const Str& msg){ _error("ValueError", msg); }
void NameError(StrName name){ _error("NameError", fmt("name ", name.escape() + " is not defined")); } void NameError(StrName name){ _error("NameError", fmt("name ", name.escape() + " is not defined")); }