This commit is contained in:
BLUELOVETH 2023-04-08 06:36:13 +00:00
parent 95c3644dc2
commit e03ce955fc
7 changed files with 38 additions and 33 deletions

View File

@ -53,14 +53,22 @@ __NEXT_STEP:;
case OP_LOAD_NAME: { case OP_LOAD_NAME: {
StrName name = frame->co->names[byte.arg]; StrName name = frame->co->names[byte.arg];
PyObject* val; PyObject* val;
int i = 0; // names[0] is ensured to be non-null val = frame->f_locals().try_get(name);
do{ if(val != nullptr) { frame->push(val); DISPATCH(); }
val = frame->names[i++]->try_get(name); val = frame->f_closure_try_get(name);
if(val != nullptr){ if(val != nullptr) { frame->push(val); DISPATCH(); }
frame->push(val); val = frame->f_globals().try_get(name);
DISPATCH(); if(val != nullptr) { frame->push(val); DISPATCH(); }
} val = vm->builtins->attr().try_get(name);
}while(frame->names[i] != nullptr); if(val != nullptr) { frame->push(val); DISPATCH(); }
vm->NameError(name);
} DISPATCH();
case OP_LOAD_GLOBAL: {
StrName name = frame->co->names[byte.arg];
PyObject* val = frame->f_globals().try_get(name);
if(val != nullptr) { frame->push(val); DISPATCH(); }
val = vm->builtins->attr().try_get(name);
if(val != nullptr) { frame->push(val); DISPATCH(); }
vm->NameError(name); vm->NameError(name);
} DISPATCH(); } DISPATCH();
case OP_LOAD_ATTR: { case OP_LOAD_ATTR: {
@ -319,7 +327,7 @@ __NEXT_STEP:;
} }
CodeObject_ code = compile(source, name.str(), EXEC_MODE); CodeObject_ code = compile(source, name.str(), EXEC_MODE);
PyObject* new_mod = new_module(name); PyObject* new_mod = new_module(name);
_exec(code, new_mod, builtins); _exec(code, new_mod);
new_mod->attr()._try_perfect_rehash(); new_mod->attr()._try_perfect_rehash();
frame->push(new_mod); frame->push(new_mod);
}else{ }else{

View File

@ -41,7 +41,7 @@
#define DEBUG_NO_AUTO_GC 0 #define DEBUG_NO_AUTO_GC 0
#define DEBUG_GC_STATS 0 #define DEBUG_GC_STATS 0
#define DEBUG_FRAME_USE_POOL 1 #define DEBUG_FRAME_USE_POOL 0
#if (defined(__ANDROID__) && __ANDROID_API__ <= 22) || defined(__EMSCRIPTEN__) #if (defined(__ANDROID__) && __ANDROID_API__ <= 22) || defined(__EMSCRIPTEN__)
#define PK_ENABLE_FILEIO 0 #define PK_ENABLE_FILEIO 0

View File

@ -812,7 +812,7 @@ __SUBSCR_END:
consume(TK(")")); consume(TK(")"));
} }
if(super_namei == -1) ctx()->emit(OP_LOAD_NONE, BC_NOARG, prev().line); if(super_namei == -1) ctx()->emit(OP_LOAD_NONE, BC_NOARG, prev().line);
else ctx()->emit(OP_LOAD_NAME, super_namei, prev().line); else ctx()->emit(OP_LOAD_GLOBAL, super_namei, prev().line);
ctx()->emit(OP_BEGIN_CLASS, namei, BC_KEEPLINE); ctx()->emit(OP_BEGIN_CLASS, namei, BC_KEEPLINE);
ctx()->is_compiling_class = true; ctx()->is_compiling_class = true;
compile_block_body(); compile_block_body();
@ -894,7 +894,7 @@ __SUBSCR_END:
auto e = make_expr<NameExpr>(decl->name, name_scope()); auto e = make_expr<NameExpr>(decl->name, name_scope());
e->emit_store(ctx()); e->emit_store(ctx());
} else { } else {
ctx()->emit(OP_LOAD_NAME, ctx()->add_name(obj_name), prev().line); ctx()->emit(OP_LOAD_GLOBAL, ctx()->add_name(obj_name), prev().line);
int index = ctx()->add_name(decl->name); int index = ctx()->add_name(decl->name);
ctx()->emit(OP_STORE_ATTR, index, prev().line); ctx()->emit(OP_STORE_ATTR, index, prev().line);
} }

View File

@ -21,21 +21,16 @@ struct Frame {
NameDict_ _closure; NameDict_ _closure;
const uint64_t id; const uint64_t id;
std::vector<std::pair<int, ValueStack>> s_try_block; std::vector<std::pair<int, ValueStack>> s_try_block;
const NameDict* names[5]; // name resolution array, zero terminated
NameDict& f_locals() noexcept { return *_locals; } NameDict& f_locals() noexcept { return _locals!=nullptr ? *_locals : _module->attr(); }
NameDict& f_globals() noexcept { return _module->attr(); } NameDict& f_globals() noexcept { return _module->attr(); }
PyObject* f_closure_try_get(StrName name){
Frame(const CodeObject_& co, PyObject* _module, PyObject* builtins, NameDict_ _locals=nullptr, NameDict_ _closure=nullptr) if(_closure == nullptr) return nullptr;
: co(co.get()), _module(_module), _locals(_locals), _closure(_closure), id(kFrameGlobalId++) { return _closure->try_get(name);
memset(names, 0, sizeof(names));
int i = 0;
if(_locals != nullptr) names[i++] = _locals.get();
if(_closure != nullptr) names[i++] = _closure.get();
names[i++] = &_module->attr(); // borrowed reference
if(builtins != nullptr){
names[i++] = &builtins->attr(); // borrowed reference
} }
Frame(const CodeObject_& co, PyObject* _module, NameDict_ _locals=nullptr, NameDict_ _closure=nullptr)
: co(co.get()), _module(_module), _locals(_locals), _closure(_closure), id(kFrameGlobalId++) {
} }
const Bytecode& next_bytecode() { const Bytecode& next_bytecode() {

View File

@ -18,6 +18,7 @@ OPCODE(LOAD_FUNCTION)
OPCODE(LOAD_NULL) OPCODE(LOAD_NULL)
/**************************/ /**************************/
OPCODE(LOAD_NAME) OPCODE(LOAD_NAME)
OPCODE(LOAD_GLOBAL)
OPCODE(LOAD_ATTR) OPCODE(LOAD_ATTR)
OPCODE(LOAD_METHOD) OPCODE(LOAD_METHOD)
OPCODE(LOAD_SUBSCR) OPCODE(LOAD_SUBSCR)

View File

@ -98,12 +98,12 @@ inline void init_builtins(VM* _vm) {
_vm->bind_builtin_func<1>("eval", [](VM* vm, Args& args) { _vm->bind_builtin_func<1>("eval", [](VM* vm, Args& args) {
CodeObject_ code = vm->compile(CAST(Str&, args[0]), "<eval>", EVAL_MODE); CodeObject_ code = vm->compile(CAST(Str&, args[0]), "<eval>", EVAL_MODE);
return vm->_exec(code, vm->top_frame()->_module, vm->builtins, vm->top_frame()->_locals); return vm->_exec(code, vm->top_frame()->_module, vm->top_frame()->_locals);
}); });
_vm->bind_builtin_func<1>("exec", [](VM* vm, Args& args) { _vm->bind_builtin_func<1>("exec", [](VM* vm, Args& args) {
CodeObject_ code = vm->compile(CAST(Str&, args[0]), "<exec>", EXEC_MODE); CodeObject_ code = vm->compile(CAST(Str&, args[0]), "<exec>", EXEC_MODE);
vm->_exec(code, vm->top_frame()->_module, vm->builtins, vm->top_frame()->_locals); vm->_exec(code, vm->top_frame()->_module, vm->top_frame()->_locals);
return vm->None; return vm->None;
}); });
@ -601,7 +601,7 @@ inline void add_module_json(VM* vm){
vm->bind_func<1>(mod, "loads", [](VM* vm, Args& args) { vm->bind_func<1>(mod, "loads", [](VM* vm, Args& args) {
const Str& expr = CAST(Str&, args[0]); const Str& expr = CAST(Str&, args[0]);
CodeObject_ code = vm->compile(expr, "<json>", JSON_MODE); CodeObject_ code = vm->compile(expr, "<json>", JSON_MODE);
return vm->_exec(code, vm->top_frame()->_module, vm->builtins, vm->top_frame()->_locals); return vm->_exec(code, vm->top_frame()->_module, vm->top_frame()->_locals);
}); });
vm->bind_func<1>(mod, "dumps", CPP_LAMBDA(vm->fast_call(__json__, Args{args[0]}))); vm->bind_func<1>(mod, "dumps", CPP_LAMBDA(vm->fast_call(__json__, Args{args[0]})));
@ -754,7 +754,7 @@ inline void add_module_random(VM* vm){
PyObject* mod = vm->new_module("random"); PyObject* mod = vm->new_module("random");
Random::register_class(vm, mod); Random::register_class(vm, mod);
CodeObject_ code = vm->compile(kPythonLibs["random"], "random.py", EXEC_MODE); CodeObject_ code = vm->compile(kPythonLibs["random"], "random.py", EXEC_MODE);
vm->_exec(code, mod, vm->builtins); vm->_exec(code, mod);
} }
inline void add_module_gc(VM* vm){ inline void add_module_gc(VM* vm){
@ -782,11 +782,11 @@ inline void VM::post_init(){
} }
CodeObject_ code = compile(kPythonLibs["builtins"], "<builtins>", EXEC_MODE); CodeObject_ code = compile(kPythonLibs["builtins"], "<builtins>", EXEC_MODE);
this->_exec(code, this->builtins, nullptr); this->_exec(code, this->builtins);
code = compile(kPythonLibs["_dict"], "<builtins>", EXEC_MODE); code = compile(kPythonLibs["_dict"], "<builtins>", EXEC_MODE);
this->_exec(code, this->builtins, nullptr); this->_exec(code, this->builtins);
code = compile(kPythonLibs["_set"], "<builtins>", EXEC_MODE); code = compile(kPythonLibs["_set"], "<builtins>", EXEC_MODE);
this->_exec(code, this->builtins, nullptr); this->_exec(code, this->builtins);
// property is defined in builtins.py so we need to add it after builtins is loaded // property is defined in builtins.py so we need to add it after builtins is loaded
_t(tp_object)->attr().set(__class__, property(CPP_LAMBDA(vm->_t(args[0])))); _t(tp_object)->attr().set(__class__, property(CPP_LAMBDA(vm->_t(args[0]))));

View File

@ -169,7 +169,7 @@ public:
#if DEBUG_DIS_EXEC #if DEBUG_DIS_EXEC
if(_module == _main) std::cout << disassemble(code) << '\n'; if(_module == _main) std::cout << disassemble(code) << '\n';
#endif #endif
return _exec(code, _module, builtins); return _exec(code, _module);
}catch (const Exception& e){ }catch (const Exception& e){
*_stderr << e.summary() << '\n'; *_stderr << e.summary() << '\n';
@ -600,7 +600,8 @@ inline Str VM::disassemble(CodeObject_ co){
case OP_LOAD_CONST: case OP_LOAD_CONST:
argStr += " (" + CAST(Str, asRepr(co->consts[byte.arg])) + ")"; argStr += " (" + CAST(Str, asRepr(co->consts[byte.arg])) + ")";
break; break;
case OP_LOAD_NAME: case OP_STORE_LOCAL: case OP_STORE_GLOBAL: case OP_LOAD_NAME: case OP_LOAD_GLOBAL:
case OP_STORE_LOCAL: case OP_STORE_GLOBAL:
case OP_LOAD_ATTR: case OP_LOAD_METHOD: case OP_STORE_ATTR: case OP_DELETE_ATTR: case OP_LOAD_ATTR: case OP_LOAD_METHOD: case OP_STORE_ATTR: case OP_DELETE_ATTR:
case OP_IMPORT_NAME: case OP_BEGIN_CLASS: case OP_IMPORT_NAME: case OP_BEGIN_CLASS:
case OP_DELETE_LOCAL: case OP_DELETE_GLOBAL: case OP_DELETE_LOCAL: case OP_DELETE_GLOBAL:
@ -764,7 +765,7 @@ inline PyObject* VM::call(PyObject* callable, Args args, const Args& kwargs, boo
locals->set(key, kwargs[i+1]); locals->set(key, kwargs[i+1]);
} }
PyObject* _module = fn._module != nullptr ? fn._module : top_frame()->_module; PyObject* _module = fn._module != nullptr ? fn._module : top_frame()->_module;
auto _frame = _new_frame(fn.decl->code, _module, builtins, locals, fn._closure); auto _frame = _new_frame(fn.decl->code, _module, locals, fn._closure);
if(fn.decl->code->is_generator) return PyIter(Generator(this, std::move(_frame))); if(fn.decl->code->is_generator) return PyIter(Generator(this, std::move(_frame)));
callstack.push(std::move(_frame)); callstack.push(std::move(_frame));
if(opCall) return _py_op_call; if(opCall) return _py_op_call;