improve exec/eval

This commit is contained in:
blueloveTH 2023-10-12 00:44:53 +08:00
parent cc1121f57d
commit 3a3b97c070
3 changed files with 29 additions and 84 deletions

View File

@ -72,7 +72,6 @@ static dylib_entry_t load_dylib(const char* path){
} }
#endif #endif
void init_builtins(VM* _vm) { void init_builtins(VM* _vm) {
#define BIND_NUM_ARITH_OPT(name, op) \ #define BIND_NUM_ARITH_OPT(name, op) \
_vm->bind##name(_vm->tp_int, [](VM* vm, PyObject* lhs, PyObject* rhs) { \ _vm->bind##name(_vm->tp_int, [](VM* vm, PyObject* lhs, PyObject* rhs) { \
@ -238,16 +237,29 @@ void init_builtins(VM* _vm) {
} }
}); });
_vm->bind_builtin_func<1>("eval", [](VM* vm, ArgsView args) { _vm->bind(_vm->builtins, "eval(__source, __globals=None)", [](VM* vm, ArgsView args) {
CodeObject_ code = vm->compile(CAST(Str&, args[0]), "<eval>", EVAL_MODE, true); CodeObject_ code = vm->compile(CAST(Str&, args[0]), "<eval>", EVAL_MODE, true);
FrameId frame = vm->top_frame(); PyObject* globals = args[1];
return vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals); if(globals == vm->None){
FrameId frame = vm->top_frame();
return vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals);
}
vm->check_non_tagged_type(globals, vm->tp_mappingproxy);
PyObject* obj = PK_OBJ_GET(MappingProxy, globals).obj;
return vm->_exec(code, obj);
}); });
_vm->bind_builtin_func<1>("exec", [](VM* vm, ArgsView args) { _vm->bind(_vm->builtins, "exec(__source, __globals=None)", [](VM* vm, ArgsView args) {
CodeObject_ code = vm->compile(CAST(Str&, args[0]), "<exec>", EXEC_MODE, true); CodeObject_ code = vm->compile(CAST(Str&, args[0]), "<exec>", EXEC_MODE, true);
FrameId frame = vm->top_frame(); PyObject* globals = args[1];
vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals); if(globals == vm->None){
FrameId frame = vm->top_frame();
vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals);
return vm->None;
}
vm->check_non_tagged_type(globals, vm->tp_mappingproxy);
PyObject* obj = PK_OBJ_GET(MappingProxy, globals).obj;
vm->_exec(code, obj);
return vm->None; return vm->None;
}); });
@ -983,32 +995,6 @@ void init_builtins(VM* _vm) {
return VAR(val ? "true" : "false"); return VAR(val ? "true" : "false");
}); });
const PK_LOCAL_STATIC auto f_bool_add = [](VM* vm, PyObject* lhs, PyObject* rhs) -> PyObject* {
int x = (int)_CAST(bool, lhs);
if(is_int(rhs)) return VAR(x + _CAST(int, rhs));
if(rhs == vm->True) return VAR(x + 1);
if(rhs == vm->False) return VAR(x);
return vm->NotImplemented;
};
const PK_LOCAL_STATIC auto f_bool_mul = [](VM* vm, PyObject* lhs, PyObject* rhs) -> PyObject* {
int x = (int)_CAST(bool, lhs);
if(is_int(rhs)) return VAR(x * _CAST(int, rhs));
if(rhs == vm->True) return VAR(x);
if(rhs == vm->False) return VAR(0);
return vm->NotImplemented;
};
_vm->bind__add__(_vm->tp_bool, f_bool_add);
_vm->bind_method<1>("bool", "__radd__", [](VM* vm, ArgsView args){
return f_bool_add(vm, args[0], args[1]);
});
_vm->bind__mul__(_vm->tp_bool, f_bool_mul);
_vm->bind_method<1>("bool", "__rmul__", [](VM* vm, ArgsView args){
return f_bool_mul(vm, args[0], args[1]);
});
_vm->bind__and__(_vm->tp_bool, [](VM* vm, PyObject* lhs, PyObject* rhs) { _vm->bind__and__(_vm->tp_bool, [](VM* vm, PyObject* lhs, PyObject* rhs) {
return VAR(_CAST(bool, lhs) && CAST(bool, rhs)); return VAR(_CAST(bool, lhs) && CAST(bool, rhs));
}); });

View File

@ -29,4 +29,13 @@ def f():
exec( exec(
"exec('b = eval(\"3 + 5\")')" "exec('b = eval(\"3 + 5\")')"
) )
assert b == 8 assert b == 8
class G: pass
def abc():
g = G()
exec('a=1', g.__dict__)
return g.a
assert abc() == 1

View File

@ -557,56 +557,6 @@ assert repr(True) == 'True'
assert repr(False) == 'False' assert repr(False) == 'False'
# 未完全测试准确性-----------------------------------------------
# 58: 851: const PK_LOCAL_STATIC auto f_bool_add = [](VM* vm, PyObject* lhs, PyObject* rhs) -> PyObject* {
# #####: 852: int x = (int)_CAST(bool, lhs);
# #####: 853: if(is_int(rhs)) return VAR(x + _CAST(int, rhs));
# #####: 854: if(rhs == vm->True) return VAR(x + 1);
# #####: 855: if(rhs == vm->False) return VAR(x);
# #####: 856: return vm->NotImplemented;
# #####: 857: };
#
# 58: 867: _vm->bind__add__(_vm->tp_bool, f_bool_add);
# test bool.__add__:
assert type(True + 1) is int
assert type(True + False) is int
assert type(True + True) is int
# 未完全测试准确性-----------------------------------------------
# 58: 859: const PK_LOCAL_STATIC auto f_bool_mul = [](VM* vm, PyObject* lhs, PyObject* rhs) -> PyObject* {
# #####: 860: int x = (int)_CAST(bool, lhs);
# #####: 861: if(is_int(rhs)) return VAR(x * _CAST(int, rhs));
# #####: 862: if(rhs == vm->True) return VAR(x);
# #####: 863: if(rhs == vm->False) return VAR(0);
# #####: 864: return vm->NotImplemented;
# #####: 865: };
#
# 58: 872: _vm->bind__mul__(_vm->tp_bool, f_bool_mul);
# test bool.__mul__:
assert type(True * 1) is int
assert type(True * False) is int
assert type(True * True) is int
# 未完全测试准确性-----------------------------------------------
# 116: 873: _vm->bind_method<1>("bool", "__radd__", [](VM* vm, ArgsView args){
# #####: 874: return f_bool_add(vm, args[0], args[1]);
# -: 875: });
# test bool.__radd__:
assert type(1 + True) is int
# 未完全测试准确性-----------------------------------------------
# 116: 878: _vm->bind_method<1>("bool", "__rmul__", [](VM* vm, ArgsView args){
# #####: 879: return f_bool_mul(vm, args[0], args[1]);
# -: 880: });
# test bool.__rmul__:
assert type(1 * True) is int
# 未完全测试准确性----------------------------------------------- # 未完全测试准确性-----------------------------------------------
# 116: 882: _vm->bind__and__(_vm->tp_bool, [](VM* vm, PyObject* lhs, PyObject* rhs) { # 116: 882: _vm->bind__and__(_vm->tp_bool, [](VM* vm, PyObject* lhs, PyObject* rhs) {
# #####: 883: return VAR(_CAST(bool, lhs) && CAST(bool, rhs)); # #####: 883: return VAR(_CAST(bool, lhs) && CAST(bool, rhs));