Przeglądaj źródła

fix py_exec and py_eval.

ykiko 1 rok temu
rodzic
commit
cc4dd34c86
1 zmienionych plików z 19 dodań i 18 usunięć
  1. 19 18
      src/vm.cpp

+ 19 - 18
src/vm.cpp

@@ -518,33 +518,34 @@ i64 VM::py_hash(PyVar obj){
 }
 
 PyVar VM::__py_exec_internal(const CodeObject_& code, PyVar globals, PyVar locals){
-    Frame* frame = &vm->callstack.top();
+    Frame* frame = nullptr;
+    if(!callstack.empty()) frame = &callstack.top();
 
     // fast path
-    if(globals == vm->None && locals == vm->None){
+    if(frame && globals == vm->None && locals == vm->None) {
         return vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals);
     }
 
     auto _lock = heap.gc_scope_lock();  // for safety
 
-    PyVar globals_obj = nullptr;
+    PyObject* globals_obj = nullptr;
     Dict* globals_dict = nullptr;
 
     NameDict_ locals_closure = nullptr;
     Dict* locals_dict = nullptr;
 
-    if(globals == vm->None){
-        globals_obj = frame->_module;
-    }else{
-        if(is_type(globals, VM::tp_mappingproxy)){
+    if(globals == vm->None) {
+        globals_obj = frame ? frame->_module : _main;
+    } else {
+        if(is_type(globals, VM::tp_mappingproxy)) {
             globals_obj = PK_OBJ_GET(MappingProxy, globals).obj;
-        }else{
+        } else {
             check_compatible_type(globals, VM::tp_dict);
             // make a temporary object and copy globals into it
             globals_obj = heap.gcnew<DummyInstance>(VM::tp_object);
             globals_obj->_enable_instance_dict();
             globals_dict = &PK_OBJ_GET(Dict, globals);
-            globals_dict->apply([&](PyVar k, PyVar v){
+            globals_dict->apply([&](PyVar k, PyVar v) {
                 globals_obj->attr().set(CAST(Str&, k), v);
             });
         }
@@ -552,29 +553,29 @@ PyVar VM::__py_exec_internal(const CodeObject_& code, PyVar globals, PyVar local
 
     PyVar retval = nullptr;
 
-    if(locals == vm->None){
-        retval = vm->_exec(code, globals_obj);   // only globals
-    }else{
+    if(locals == vm->None) {
+        retval = vm->_exec(code, globals_obj);  // only globals
+    } else {
         check_compatible_type(locals, VM::tp_dict);
         locals_dict = &PK_OBJ_GET(Dict, locals);
         locals_closure = std::make_shared<NameDict>();
-        locals_dict->apply([&](PyVar k, PyVar v){
+        locals_dict->apply([&](PyVar k, PyVar v) {
             locals_closure->set(CAST(Str&, k), v);
         });
-        PyVar _callable = VAR(Function(__dynamic_func_decl, globals_obj, nullptr, locals_closure));
+        PyObject* _callable = VAR(Function(__dynamic_func_decl, globals_obj, nullptr, locals_closure));
         retval = vm->_exec(code.get(), globals_obj, _callable, vm->s_data._sp);
     }
 
-    if(globals_dict){
+    if(globals_dict) {
         globals_dict->clear();
-        globals_obj->attr().apply([&](StrName k, PyVar v){
+        globals_obj->attr().apply([&](StrName k, PyVar v) {
             globals_dict->set(VAR(k.sv()), v);
         });
     }
 
-    if(locals_dict){
+    if(locals_dict) {
         locals_dict->clear();
-        locals_closure->apply([&](StrName k, PyVar v){
+        locals_closure->apply([&](StrName k, PyVar v) {
             locals_dict->set(VAR(k.sv()), v);
         });
     }