remove CodeObject_

This commit is contained in:
blueloveTH 2024-06-22 15:46:48 +08:00
parent 58c5bb1d35
commit 28c3b35d39
11 changed files with 75 additions and 54 deletions

View File

@ -54,7 +54,7 @@ struct Compiler {
CompileMode mode() const noexcept{ return lexer.src->mode; } CompileMode mode() const noexcept{ return lexer.src->mode; }
NameScope name_scope() const noexcept; NameScope name_scope() const noexcept;
CodeObject_ push_global_context() noexcept; CodeObject* push_global_context() noexcept;
FuncDecl_ push_f_context(Str name) noexcept; FuncDecl_ push_f_context(Str name) noexcept;
static void init_pratt_rules() noexcept; static void init_pratt_rules() noexcept;
@ -134,7 +134,7 @@ struct Compiler {
public: public:
Compiler(VM* vm, std::string_view source, const Str& filename, CompileMode mode, bool unknown_global_scope = false) noexcept; Compiler(VM* vm, std::string_view source, const Str& filename, CompileMode mode, bool unknown_global_scope = false) noexcept;
[[nodiscard]] Error* compile(CodeObject_* out) noexcept; [[nodiscard]] Error* compile(CodeObject** out) noexcept;
~Compiler(); ~Compiler();
}; };

View File

@ -48,12 +48,12 @@ inline void delete_expr(Expr* p) noexcept{
struct CodeEmitContext{ struct CodeEmitContext{
VM* vm; VM* vm;
FuncDecl_ func; // optional FuncDecl_ func; // optional
CodeObject_ co; // 1 CodeEmitContext <=> 1 CodeObject_ CodeObject* co; // 1 CodeEmitContext <=> 1 CodeObject*
vector<Expr*> _s_expr; vector<Expr*> _s_expr;
int level; int level;
vector<StrName> global_names; vector<StrName> global_names;
CodeEmitContext(VM* vm, CodeObject_ co, int level) : vm(vm), co(co), level(level) { CodeEmitContext(VM* vm, CodeObject* co, int level) : vm(vm), co(co), level(level) {
c11_smallmap_s2n__ctor(&_co_consts_string_dedup_map); c11_smallmap_s2n__ctor(&_co_consts_string_dedup_map);
} }

View File

@ -130,9 +130,9 @@ struct Frame {
_uw_list(nullptr) {} _uw_list(nullptr) {}
// global scope // global scope
Frame(PyVar* p0, const CodeObject_& co, PyObject* _module) : Frame(PyVar* p0, const CodeObject* co, PyObject* _module) :
_ip(co->codes.data() - 1), _sp_base(p0), co(co.get()), _module(_module), _callable(nullptr), _ip(co->codes.data() - 1), _sp_base(p0), co(co), _module(_module), _callable(nullptr),
_locals(co.get(), p0), _uw_list(nullptr) {} _locals(co, p0), _uw_list(nullptr) {}
PyVar* actual_sp_base() const { return _locals.a; } PyVar* actual_sp_base() const { return _locals.a; }

View File

@ -265,7 +265,7 @@ public:
ArgsView cast_array_view(PyVar obj); ArgsView cast_array_view(PyVar obj);
void set_main_argv(int argc, char** argv); void set_main_argv(int argc, char** argv);
i64 normalized_index(i64 index, int size); i64 normalized_index(i64 index, int size);
Str disassemble(CodeObject_ co); Str disassemble(CodeObject* co);
void parse_int_slice(const Slice& s, int length, int& start, int& stop, int& step); void parse_int_slice(const Slice& s, int length, int& start, int& stop, int& step);
void obj_gc_mark(PyVar obj) { if(obj.is_ptr) __obj_gc_mark(obj.get()); } void obj_gc_mark(PyVar obj) { if(obj.is_ptr) __obj_gc_mark(obj.get()); }
void obj_gc_mark(PyObject* p) { if(p) __obj_gc_mark(p); } void obj_gc_mark(PyObject* p) { if(p) __obj_gc_mark(p); }
@ -280,7 +280,7 @@ public:
#endif #endif
#if PK_REGION("Source Execution Methods") #if PK_REGION("Source Execution Methods")
CodeObject_ compile(std::string_view source, const Str& filename, CompileMode mode, bool unknown_global_scope=false); CodeObject* compile(std::string_view source, const Str& filename, CompileMode mode, bool unknown_global_scope=false);
Str precompile(std::string_view source, const Str& filename, CompileMode mode); Str precompile(std::string_view source, const Str& filename, CompileMode mode);
PyVar exec(std::string_view source, Str filename, CompileMode mode, PyObject* _module=nullptr); PyVar exec(std::string_view source, Str filename, CompileMode mode, PyObject* _module=nullptr);
PyVar exec(std::string_view source); PyVar exec(std::string_view source);
@ -494,7 +494,7 @@ public:
#if PK_DEBUG_CEVAL_STEP #if PK_DEBUG_CEVAL_STEP
void __log_s_data(const char* title = nullptr); void __log_s_data(const char* title = nullptr);
#endif #endif
PyVar __py_exec_internal(const CodeObject_& code, PyVar globals, PyVar locals); PyVar __py_exec_internal(const CodeObject* code, PyVar globals, PyVar locals);
void __breakpoint(); void __breakpoint();
PyVar __format_object(PyVar, Str); PyVar __format_object(PyVar, Str);
PyVar __run_top_frame(); PyVar __run_top_frame();

View File

@ -14,7 +14,6 @@ typedef PyVar (*NativeFuncC)(VM*, ArgsView);
struct CodeObject; struct CodeObject;
struct FuncDecl; struct FuncDecl;
using CodeObject_ = std::shared_ptr<CodeObject>;
using FuncDecl_ = std::shared_ptr<FuncDecl>; using FuncDecl_ = std::shared_ptr<FuncDecl>;
struct CodeObject { struct CodeObject {
@ -69,7 +68,7 @@ struct FuncDecl {
PyVar value; // default value PyVar value; // default value
}; };
CodeObject_ code; // code object of this function CodeObject* code; // strong ref
small_vector_2<int, 8> args; // indices in co->varnames small_vector_2<int, 8> args; // indices in co->varnames
c11_vector/*T=KwArg*/ kwargs; // indices in co->varnames c11_vector/*T=KwArg*/ kwargs; // indices in co->varnames
@ -90,12 +89,14 @@ struct FuncDecl {
void _gc_mark(VM*) const; void _gc_mark(VM*) const;
FuncDecl(){ FuncDecl(CodeObject* code){
this->code = code;
c11_vector__ctor(&kwargs, sizeof(KwArg)); c11_vector__ctor(&kwargs, sizeof(KwArg));
c11_smallmap_n2i__ctor(&kw_to_index); c11_smallmap_n2i__ctor(&kw_to_index);
} }
~FuncDecl(){ ~FuncDecl(){
delete code;
c11_vector__dtor(&kwargs); c11_vector__dtor(&kwargs);
c11_smallmap_n2i__dtor(&kw_to_index); c11_smallmap_n2i__dtor(&kw_to_index);
} }

View File

@ -1,6 +1,7 @@
#include "pocketpy/compiler/compiler.hpp" #include "pocketpy/compiler/compiler.hpp"
#include "pocketpy/common/config.h" #include "pocketpy/common/config.h"
#include "pocketpy/interpreter/vm.hpp" #include "pocketpy/interpreter/vm.hpp"
#include "pocketpy/objects/codeobject.hpp"
#include <cstdarg> #include <cstdarg>
@ -19,16 +20,16 @@ NameScope Compiler::name_scope() const noexcept{
return s; return s;
} }
CodeObject_ Compiler::push_global_context() noexcept{ CodeObject* Compiler::push_global_context() noexcept{
CodeObject_ co = std::make_shared<CodeObject>(lexer.src, static_cast<const Str&>(lexer.src->filename)); CodeObject* co = new CodeObject(lexer.src, static_cast<const Str&>(lexer.src->filename));
co->start_line = __i == 0 ? 1 : prev().line; co->start_line = __i == 0 ? 1 : prev().line;
contexts.push_back(CodeEmitContext(vm, co, contexts.size())); contexts.push_back(CodeEmitContext(vm, co, contexts.size()));
return co; return co;
} }
FuncDecl_ Compiler::push_f_context(Str name) noexcept{ FuncDecl_ Compiler::push_f_context(Str name) noexcept{
FuncDecl_ decl = std::make_shared<FuncDecl>(); CodeObject* co = new CodeObject(lexer.src, name);
decl->code = std::make_shared<CodeObject>(lexer.src, name); FuncDecl_ decl = std::make_shared<FuncDecl>(co);
decl->code->start_line = __i == 0 ? 1 : prev().line; decl->code->start_line = __i == 0 ? 1 : prev().line;
decl->nested = name_scope() == NAME_LOCAL; decl->nested = name_scope() == NAME_LOCAL;
contexts.push_back(CodeEmitContext(vm, decl->code, contexts.size())); contexts.push_back(CodeEmitContext(vm, decl->code, contexts.size()));
@ -1290,7 +1291,7 @@ Compiler::Compiler(VM* vm, std::string_view source, const Str& filename, Compile
init_pratt_rules(); init_pratt_rules();
} }
Error* Compiler::compile(CodeObject_* out) noexcept{ Error* Compiler::compile(CodeObject** out) noexcept{
assert(__i == 0); // make sure it is the first time to compile assert(__i == 0); // make sure it is the first time to compile
Error* err; Error* err;
@ -1303,7 +1304,7 @@ Error* Compiler::compile(CodeObject_* out) noexcept{
// } // }
// } // }
CodeObject_ code = push_global_context(); CodeObject* code = push_global_context();
assert(curr().type == TK_SOF); assert(curr().type == TK_SOF);
advance(); // skip @sof, so prev() is always valid advance(); // skip @sof, so prev() is always valid

View File

@ -795,8 +795,9 @@ PyVar VM::__run_top_frame() {
PyVar _0 = frame->co->consts[byte.arg]; PyVar _0 = frame->co->consts[byte.arg];
std::string_view string = CAST(Str&, _0).sv(); std::string_view string = CAST(Str&, _0).sv();
// TODO: optimize this // TODO: optimize this
CodeObject_ code = vm->compile(string, "<eval>", EVAL_MODE, true); CodeObject* code = vm->compile(string, "<eval>", EVAL_MODE, true);
_0 = vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals); _0 = vm->_exec(code, frame->_module, frame->_callable, frame->_locals);
delete code; // leak on error
PUSH(_0); PUSH(_0);
} }
DISPATCH() DISPATCH()

View File

@ -201,13 +201,16 @@ bool VM::issubclass(Type cls, Type base) {
PyVar VM::exec(std::string_view source, Str filename, CompileMode mode, PyObject* _module) { PyVar VM::exec(std::string_view source, Str filename, CompileMode mode, PyObject* _module) {
if(_module == nullptr) _module = _main; if(_module == nullptr) _module = _main;
CodeObject* code = NULL;
try { try {
#if PK_DEBUG_PRECOMPILED_EXEC == 1 #if PK_DEBUG_PRECOMPILED_EXEC == 1
Str precompiled = vm->precompile(source, filename, mode); Str precompiled = vm->precompile(source, filename, mode);
source = precompiled.sv(); source = precompiled.sv();
#endif #endif
CodeObject_ code = compile(source, filename, mode); code = compile(source, filename, mode);
return _exec(code, _module); PyVar retval = _exec(code, _module);
delete code; // leak if exception occurs
return retval;
} catch(TopLevelException e) { } catch(TopLevelException e) {
stderr_write(e.summary() + "\n"); stderr_write(e.summary() + "\n");
} catch(const std::exception& e) { } catch(const std::exception& e) {
@ -218,6 +221,7 @@ PyVar VM::exec(std::string_view source, Str filename, CompileMode mode, PyObject
Str msg = "An unknown exception occurred! It could be a bug. Please report it to @blueloveTH on GitHub.\n"; Str msg = "An unknown exception occurred! It could be a bug. Please report it to @blueloveTH on GitHub.\n";
stderr_write(msg); stderr_write(msg);
} }
delete code;
callstack.clear(); callstack.clear();
s_data.clear(); s_data.clear();
return nullptr; return nullptr;
@ -410,12 +414,12 @@ PyObject* VM::py_import(Str path, bool throw_err) {
// _lazy_modules.erase(it); // no need to erase // _lazy_modules.erase(it); // no need to erase
} }
auto _ = __import_context.scope(path, is_init); auto _ = __import_context.scope(path, is_init);
CodeObject_ code = compile(source, filename, EXEC_MODE);
Str name_cpnt = path_cpnts.back(); Str name_cpnt = path_cpnts.back();
path_cpnts.pop_back(); path_cpnts.pop_back();
PyObject* new_mod = new_module(name_cpnt, f_join(path_cpnts)); PyObject* new_mod = new_module(name_cpnt, f_join(path_cpnts));
CodeObject* code = compile(source, filename, EXEC_MODE);
_exec(code, new_mod); _exec(code, new_mod);
delete code; // leak if exception occurs
return new_mod; return new_mod;
} }
@ -556,13 +560,13 @@ i64 VM::py_hash(PyVar obj) {
} }
} }
PyVar VM::__py_exec_internal(const CodeObject_& code, PyVar globals, PyVar locals) { PyVar VM::__py_exec_internal(const CodeObject* code, PyVar globals, PyVar locals) {
Frame* frame = nullptr; Frame* frame = nullptr;
if(!callstack.empty()) frame = &callstack.top(); if(!callstack.empty()) frame = &callstack.top();
// fast path // fast path
if(frame && is_none(globals) && is_none(locals)) { if(frame && is_none(globals) && is_none(locals)) {
return vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals); return vm->_exec(code, frame->_module, frame->_callable, frame->_locals);
} }
auto _lock = gc_scope_lock(); // for safety auto _lock = gc_scope_lock(); // for safety
@ -602,7 +606,7 @@ PyVar VM::__py_exec_internal(const CodeObject_& code, PyVar globals, PyVar local
}); });
PyObject* _callable = PyObject* _callable =
new_object<Function>(tp_function, __dynamic_func_decl, globals_obj, nullptr, locals_closure).get(); new_object<Function>(tp_function, __dynamic_func_decl, globals_obj, nullptr, locals_closure).get();
retval = vm->_exec(code.get(), globals_obj, _callable, vm->s_data._sp); retval = vm->_exec(code, globals_obj, _callable, vm->s_data._sp);
} }
if(globals_dict) { if(globals_dict) {
@ -622,12 +626,12 @@ PyVar VM::__py_exec_internal(const CodeObject_& code, PyVar globals, PyVar local
} }
void VM::py_exec(std::string_view source, PyVar globals, PyVar locals) { void VM::py_exec(std::string_view source, PyVar globals, PyVar locals) {
CodeObject_ code = vm->compile(source, "<exec>", EXEC_MODE, true); CodeObject* code = vm->compile(source, "<exec>", EXEC_MODE, true);
__py_exec_internal(code, globals, locals); __py_exec_internal(code, globals, locals);
} }
PyVar VM::py_eval(std::string_view source, PyVar globals, PyVar locals) { PyVar VM::py_eval(std::string_view source, PyVar globals, PyVar locals) {
CodeObject_ code = vm->compile(source, "<eval>", EVAL_MODE, true); CodeObject* code = vm->compile(source, "<eval>", EVAL_MODE, true);
return __py_exec_internal(code, globals, locals); return __py_exec_internal(code, globals, locals);
} }
@ -775,7 +779,7 @@ static std::string _opcode_argstr(VM* vm, int i, Bytecode byte, const CodeObject
return ss.str().str(); return ss.str().str();
} }
Str VM::disassemble(CodeObject_ co) { Str VM::disassemble(CodeObject* co) {
auto pad = [](const Str& s, const int n) { auto pad = [](const Str& s, const int n) {
if(s.length() >= n) return s.slice(0, n); if(s.length() >= n) return s.slice(0, n);
return s + std::string(n - s.length(), ' '); return s + std::string(n - s.length(), ' ');
@ -810,7 +814,7 @@ Str VM::disassemble(CodeObject_ co) {
std::string bc_name(OP_NAMES[byte.op]); std::string bc_name(OP_NAMES[byte.op]);
if(co->lines[i].is_virtual) bc_name += '*'; if(co->lines[i].is_virtual) bc_name += '*';
ss << " " << pad(bc_name, 25) << " "; ss << " " << pad(bc_name, 25) << " ";
std::string argStr = _opcode_argstr(this, i, byte, co.get()); std::string argStr = _opcode_argstr(this, i, byte, co);
ss << argStr; ss << argStr;
if(i != co->codes.size() - 1) ss << '\n'; if(i != co->codes.size() - 1) ss << '\n';
} }
@ -983,7 +987,7 @@ void VM::__unpack_as_dict(ArgsView args, Dict& dict) {
} }
void VM::__prepare_py_call(PyVar* buffer, ArgsView args, ArgsView kwargs, const FuncDecl_& decl) { void VM::__prepare_py_call(PyVar* buffer, ArgsView args, ArgsView kwargs, const FuncDecl_& decl) {
const CodeObject* co = decl->code.get(); const CodeObject* co = decl->code;
int decl_argc = decl->args.size(); int decl_argc = decl->args.size();
if(args.size() < decl_argc) { if(args.size() < decl_argc) {
@ -1070,7 +1074,7 @@ PyVar VM::vectorcall(int ARGC, int KWARGC, bool op_call) {
if(s_data.is_overflow()) StackOverflowError(); if(s_data.is_overflow()) StackOverflowError();
const Function& fn = PK_OBJ_GET(Function, callable); const Function& fn = PK_OBJ_GET(Function, callable);
const CodeObject* co = fn.decl->code.get(); const CodeObject* co = fn.decl->code;
switch(fn.decl->type) { switch(fn.decl->type) {
case FuncType_NORMAL: case FuncType_NORMAL:
@ -1380,10 +1384,10 @@ PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, Native
int length = snprintf(buffer, sizeof(buffer), "def %s : pass", sig); int length = snprintf(buffer, sizeof(buffer), "def %s : pass", sig);
std::string_view source(buffer, length); std::string_view source(buffer, length);
// fn(a, b, *c, d=1) -> None // fn(a, b, *c, d=1) -> None
CodeObject_ co = compile(source, "<bind>", EXEC_MODE); CodeObject* code = compile(source, "<bind>", EXEC_MODE);
assert(co->func_decls.size() == 1); assert(code->func_decls.size() == 1);
FuncDecl_ decl = code->func_decls[0];
FuncDecl_ decl = co->func_decls[0]; delete code; // may leak if exception occurs
decl->docstring = docstring; decl->docstring = docstring;
PyObject* f_obj = new_object<NativeFunc>(tp_native_func, fn, decl, std::move(userdata)).get(); PyObject* f_obj = new_object<NativeFunc>(tp_native_func, fn, decl, std::move(userdata)).get();
@ -1796,13 +1800,15 @@ void VM::__breakpoint() {
std::string arg = line.substr(space + 1); std::string arg = line.substr(space + 1);
if(arg.empty()) continue; // ignore empty command if(arg.empty()) continue; // ignore empty command
if(cmd == "p" || cmd == "print") { if(cmd == "p" || cmd == "print") {
CodeObject_ code = compile(arg, "<stdin>", EVAL_MODE, true); CodeObject* code = compile(arg, "<stdin>", EVAL_MODE, true);
PyVar retval = vm->_exec(code.get(), frame_0->_module, frame_0->_callable, frame_0->_locals); PyVar retval = vm->_exec(code, frame_0->_module, frame_0->_callable, frame_0->_locals);
delete code;
stdout_write(vm->py_repr(retval)); stdout_write(vm->py_repr(retval));
stdout_write("\n"); stdout_write("\n");
} else if(cmd == "!") { } else if(cmd == "!") {
CodeObject_ code = compile(arg, "<stdin>", EXEC_MODE, true); CodeObject* code = compile(arg, "<stdin>", EXEC_MODE, true);
vm->_exec(code.get(), frame_0->_module, frame_0->_callable, frame_0->_locals); vm->_exec(code, frame_0->_module, frame_0->_callable, frame_0->_locals);
delete code;
} }
continue; continue;
} }

View File

@ -106,8 +106,10 @@ void add_module_json(VM* vm) {
} else { } else {
sv = CAST(Str&, args[0]).sv(); sv = CAST(Str&, args[0]).sv();
} }
CodeObject_ code = vm->compile(sv, "<json>", JSON_MODE); CodeObject* code = vm->compile(sv, "<json>", JSON_MODE);
return vm->_exec(code, vm->callstack.top()._module); PyVar retval = vm->_exec(code, vm->callstack.top()._module);
delete code; // leak on error
return retval;
}); });
vm->bind_func(mod, "dumps", 1, [](VM* vm, ArgsView args) { vm->bind_func(mod, "dumps", 1, [](VM* vm, ArgsView args) {
@ -224,16 +226,19 @@ void add_module_dis(VM* vm) {
PyObject* mod = vm->new_module("dis"); PyObject* mod = vm->new_module("dis");
vm->bind_func(mod, "dis", 1, [](VM* vm, ArgsView args) { vm->bind_func(mod, "dis", 1, [](VM* vm, ArgsView args) {
CodeObject_ code; CodeObject* code;
bool need_delete = false;
PyVar obj = args[0]; PyVar obj = args[0];
if(is_type(obj, vm->tp_str)) { if(is_type(obj, vm->tp_str)) {
const Str& source = CAST(Str, obj); const Str& source = CAST(Str, obj);
code = vm->compile(source, "<dis>", EXEC_MODE); code = vm->compile(source, "<dis>", EXEC_MODE);
need_delete = true;
} }
PyVar f = obj; PyVar f = obj;
if(is_type(f, vm->tp_bound_method)) f = CAST(BoundMethod, obj).func; if(is_type(f, vm->tp_bound_method)) f = CAST(BoundMethod, obj).func;
code = CAST(Function&, f).decl->code; code = CAST(Function&, f).decl->code;
vm->stdout_write(vm->disassemble(code)); vm->stdout_write(vm->disassemble(code));
if(need_delete) delete code;
return vm->None; return vm->None;
}); });
} }
@ -245,8 +250,9 @@ void add_module_gc(VM* vm) {
void add_module_enum(VM* vm) { void add_module_enum(VM* vm) {
PyObject* mod = vm->new_module("enum"); PyObject* mod = vm->new_module("enum");
CodeObject_ code = vm->compile(kPythonLibs__enum, "enum.py", EXEC_MODE); CodeObject* code = vm->compile(kPythonLibs__enum, "enum.py", EXEC_MODE);
vm->_exec(code, mod); vm->_exec(code, mod);
delete code; // leak on error
PyVar Enum = mod->attr("Enum"); PyVar Enum = mod->attr("Enum");
vm->_all_types[PK_OBJ_GET(Type, Enum)].on_end_subclass = [](VM* vm, PyTypeInfo* new_ti) { vm->_all_types[PK_OBJ_GET(Type, Enum)].on_end_subclass = [](VM* vm, PyTypeInfo* new_ti) {
new_ti->subclass_enabled = false; // Enum class cannot be subclassed twice new_ti->subclass_enabled = false; // Enum class cannot be subclassed twice

View File

@ -1691,13 +1691,16 @@ void VM::__post_init_builtin_types() {
try { try {
// initialize dummy func_decl for exec/eval // initialize dummy func_decl for exec/eval
CodeObject_ dynamic_co = compile("def _(): pass", "<dynamic>", EXEC_MODE); CodeObject* code = compile("def _(): pass", "<dynamic>", EXEC_MODE);
__dynamic_func_decl = dynamic_co->func_decls[0]; __dynamic_func_decl = code->func_decls[0];
delete code; // may leak on error
// initialize builtins // initialize builtins
CodeObject_ code = compile(kPythonLibs_builtins, "<builtins>", EXEC_MODE); code = compile(kPythonLibs_builtins, "<builtins>", EXEC_MODE);
this->_exec(code, this->builtins); this->_exec(code, this->builtins);
delete code; // may leak on error
code = compile(kPythonLibs__set, "<set>", EXEC_MODE); code = compile(kPythonLibs__set, "<set>", EXEC_MODE);
this->_exec(code, this->builtins); this->_exec(code, this->builtins);
delete code; // may leak on error
} catch(TopLevelException e) { } catch(TopLevelException e) {
std::cerr << e.summary() << std::endl; std::cerr << e.summary() << std::endl;
std::cerr << "failed to load builtins module!!" << std::endl; std::cerr << "failed to load builtins module!!" << std::endl;
@ -1723,9 +1726,9 @@ void VM::__post_init_builtin_types() {
#endif #endif
} }
CodeObject_ VM::compile(std::string_view source, const Str& filename, CompileMode mode, bool unknown_global_scope) { CodeObject* VM::compile(std::string_view source, const Str& filename, CompileMode mode, bool unknown_global_scope) {
Compiler compiler(this, source, filename, mode, unknown_global_scope); Compiler compiler(this, source, filename, mode, unknown_global_scope);
CodeObject_ code; CodeObject* code;
Error* err = compiler.compile(&code); Error* err = compiler.compile(&code);
if(err) __compile_error(err); if(err) __compile_error(err);
return code; return code;

View File

@ -60,8 +60,9 @@ bool pkpy_exec(pkpy_vm* vm_handle, const char* source) {
PK_ASSERT_NO_ERROR() PK_ASSERT_NO_ERROR()
PyVar res; PyVar res;
PK_PROTECTED( PK_PROTECTED(
CodeObject_ code = vm->compile(source, "main.py", EXEC_MODE); CodeObject* code = vm->compile(source, "main.py", EXEC_MODE);
res = vm->_exec(code, vm->_main); res = vm->_exec(code, vm->_main);
delete code; // TODO: _exec may raise, so code may leak
) )
return res != nullptr; return res != nullptr;
} }
@ -76,8 +77,9 @@ bool pkpy_exec_2(pkpy_vm* vm_handle, const char* source, const char* filename, i
}else{ }else{
mod = vm->_modules[module].get(); // may raise mod = vm->_modules[module].get(); // may raise
} }
CodeObject_ code = vm->compile(source, filename, (CompileMode)mode); CodeObject* code = vm->compile(source, filename, (CompileMode)mode);
res = vm->_exec(code, mod); res = vm->_exec(code, mod);
delete code; // TODO: _exec may raise, so code may leak
) )
return res != nullptr; return res != nullptr;
} }
@ -417,9 +419,10 @@ bool pkpy_eval(pkpy_vm* vm_handle, const char* source) {
VM* vm = (VM*)vm_handle; VM* vm = (VM*)vm_handle;
PK_ASSERT_NO_ERROR() PK_ASSERT_NO_ERROR()
PK_PROTECTED( PK_PROTECTED(
CodeObject_ co = vm->compile(source, "<eval>", EVAL_MODE); CodeObject* co = vm->compile(source, "<eval>", EVAL_MODE);
PyVar ret = vm->_exec(co, vm->_main); PyVar ret = vm->_exec(co, vm->_main);
vm->s_data.push(ret); vm->s_data.push(ret);
delete co; // TODO: _exec may raise, so code may leak
) )
return true; return true;
} }