diff --git a/include/pocketpy/opcodes.h b/include/pocketpy/opcodes.h index b9884935..6f55c956 100644 --- a/include/pocketpy/opcodes.h +++ b/include/pocketpy/opcodes.h @@ -90,7 +90,7 @@ OPCODE(LOOP_CONTINUE) OPCODE(LOOP_BREAK) OPCODE(GOTO) /**************************/ -OPCODE(EVAL_CONST) +OPCODE(FSTRING_EVAL) OPCODE(REPR) OPCODE(CALL) OPCODE(CALL_TP) diff --git a/include/pocketpy/str.h b/include/pocketpy/str.h index f7cf8b87..c7ae9514 100644 --- a/include/pocketpy/str.h +++ b/include/pocketpy/str.h @@ -225,7 +225,6 @@ const StrName __class__ = StrName::get("__class__"); const StrName pk_id_add = StrName::get("add"); const StrName pk_id_set = StrName::get("set"); -const StrName pk_id_eval = StrName::get("eval"); #define DEF_SNAME(name) const static StrName name(#name) diff --git a/include/pocketpy/vm.h b/include/pocketpy/vm.h index d0050fb1..a25979b5 100644 --- a/include/pocketpy/vm.h +++ b/include/pocketpy/vm.h @@ -136,6 +136,9 @@ public: PyObject* _last_exception; // last exception PyObject* _curr_class; // current class being defined + // cached code objects for FSTRING_EVAL + std::map _cached_codes; + #if PK_ENABLE_CEVAL_CALLBACK void (*_ceval_on_step)(VM*, Frame*, Bytecode bc) = nullptr; #endif diff --git a/src/ceval.cpp b/src/ceval.cpp index 77e146bf..9b9c3f14 100644 --- a/src/ceval.cpp +++ b/src/ceval.cpp @@ -568,10 +568,19 @@ __NEXT_STEP:; frame->jump_abs_break(index); } DISPATCH(); /*****************************************/ - TARGET(EVAL_CONST){ - PyObject* _0 = builtins->attr(pk_id_eval); - PyObject* _1 = co_consts[byte.arg]; - PUSH(call(_0, _1)); + TARGET(FSTRING_EVAL){ + PyObject* _0 = co_consts[byte.arg]; + std::string_view string = CAST(Str&, _0).sv(); + auto it = _cached_codes.find(string); + CodeObject_ code; + if(it == _cached_codes.end()){ + code = vm->compile(string, "", EVAL_MODE, true); + _cached_codes[string] = code; + }else{ + code = it->second; + } + _0 = vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals); + PUSH(_0); } DISPATCH(); TARGET(REPR) TOP() = py_repr(TOP()); diff --git a/src/expr.cpp b/src/expr.cpp index d21c57d6..ecc5e1c0 100644 --- a/src/expr.cpp +++ b/src/expr.cpp @@ -392,7 +392,7 @@ namespace pkpy{ } }else{ int index = ctx->add_const(py_var(ctx->vm, expr)); - ctx->emit_(OP_EVAL_CONST, index, line); + ctx->emit_(OP_FSTRING_EVAL, index, line); } if(repr){ ctx->emit_(OP_REPR, BC_NOARG, line); diff --git a/src/vm.cpp b/src/vm.cpp index ee018809..1036222e 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -1199,6 +1199,7 @@ void ManagedHeap::mark() { if(vm->_last_exception) PK_OBJ_MARK(vm->_last_exception); if(vm->_curr_class) PK_OBJ_MARK(vm->_curr_class); if(vm->_c.error != nullptr) PK_OBJ_MARK(vm->_c.error); + for(auto [_, co]: vm->_cached_codes) co->_gc_mark(); } Str obj_type_name(VM *vm, Type type){