blueloveTH преди 1 година
родител
ревизия
41a938386a
променени са 5 файла, в които са добавени 42 реда и са изтрити 24 реда
  1. 0 1
      include/pocketpy/interpreter/vm.h
  2. 9 0
      include/pocketpy/pocketpy.h
  3. 4 16
      src/interpreter/ceval.c
  4. 0 2
      src/interpreter/vm.c
  5. 29 5
      src/public/internal.c

+ 0 - 1
include/pocketpy/interpreter/vm.h

@@ -46,7 +46,6 @@ typedef struct VM {
     py_TValue reg[8];  // users' registers
 
     py_TValue* __curr_class;
-    FuncDecl_ __dynamic_func_decl;
     py_TValue __vectorcall_buffer[PK_MAX_CO_VARNAMES];
 
     ManagedHeap heap;

+ 9 - 0
include/pocketpy/pocketpy.h

@@ -75,6 +75,15 @@ bool py_exec(const char* source,
              enum py_CompileMode mode,
              py_Ref module) PY_RAISE;
 
+/// Run a source string in dynamic mode.
+/// Assume `globals()` and `locals()` are pushed to the stack.
+/// After the execution, the result will be set to `py_retval()`.
+/// The stack size will be reduced by 2.
+bool py_execdynamic(const char* source,
+                    const char* filename,
+                    enum py_CompileMode mode,
+                    py_Ref module) PY_RAISE;
+
 /************* Values Creation *************/
 
 /// Create an `int` object.

+ 4 - 16
src/interpreter/ceval.c

@@ -290,14 +290,8 @@ FrameResult VM__run_top_frame(VM* self) {
                     if(slot != NULL) {
                         *slot = *TOP();  // store in locals if possible
                     } else {
-                        // Function& func = frame->_callable->as<Function>();
-                        // if(func.decl == __dynamic_func_decl) {
-                        //     assert(func._closure != nullptr);
-                        //     func._closure->set(_name, _0);
-                        // } else {
-                        //     NameError(_name);
-                        //     goto __ERROR;
-                        // }
+                        NameError(name);
+                        goto __ERROR;
                     }
                 } else {
                     py_setdict(frame->module, name, TOP());
@@ -351,14 +345,8 @@ FrameResult VM__run_top_frame(VM* self) {
                     if(slot) {
                         py_newnil(slot);
                     } else {
-                        // Function& func = frame->_callable->as<Function>();
-                        // if(func.decl == __dynamic_func_decl) {
-                        //     assert(func._closure != nullptr);
-                        //     bool ok = func._closure->del(_name);
-                        //     if(!ok) vm->NameError(_name);
-                        // } else {
-                        //     vm->NameError(_name);
-                        // }
+                        NameError(name);
+                        goto __ERROR;
                     }
                 } else {
                     bool ok = py_deldict(frame->module, name);

+ 0 - 2
src/interpreter/vm.c

@@ -71,7 +71,6 @@ void VM__ctor(VM* self) {
     self->is_stopiteration = false;
 
     self->__curr_class = NULL;
-    self->__dynamic_func_decl = NULL;
 
     ManagedHeap__ctor(&self->heap, self);
     ValueStack__ctor(&self->stack);
@@ -212,7 +211,6 @@ void VM__ctor(VM* self) {
 }
 
 void VM__dtor(VM* self) {
-    if(self->__dynamic_func_decl) { PK_DECREF(self->__dynamic_func_decl); }
     // destroy all objects
     ManagedHeap__dtor(&self->heap);
     // clear frames

+ 29 - 5
src/public/internal.c

@@ -77,10 +77,14 @@ const char* pk_opname(Opcode op) {
     return OP_NAMES[op];
 }
 
-bool py_exec(const char* source, const char* filename, enum py_CompileMode mode, py_Ref module) {
+static bool _py_exec(const char* source,
+                     const char* filename,
+                     enum py_CompileMode mode,
+                     py_Ref module,
+                     bool is_dynamic) {
     VM* vm = pk_current_vm;
     CodeObject co;
-    SourceData_ src = SourceData__rcnew(source, filename, mode, false);
+    SourceData_ src = SourceData__rcnew(source, filename, mode, is_dynamic);
     Error* err = pk_compile(src, &co);
     if(err) {
         py_exception(tp_SyntaxError, err->msg);
@@ -93,7 +97,13 @@ bool py_exec(const char* source, const char* filename, enum py_CompileMode mode,
 
     if(!module) module = &vm->main;
 
-    Frame* frame = Frame__new(&co, module, false, vm->stack.sp, vm->stack.sp);
+    py_StackRef sp = vm->stack.sp;
+    if(is_dynamic) {
+        // [globals, locals]
+        sp -= 2;
+    }
+
+    Frame* frame = Frame__new(&co, module, false, sp, sp);
     VM__push_frame(vm, frame);
     FrameResult res = VM__run_top_frame(vm);
     CodeObject__dtor(&co);
@@ -103,6 +113,17 @@ bool py_exec(const char* source, const char* filename, enum py_CompileMode mode,
     c11__unreachedable();
 }
 
+bool py_exec(const char* source, const char* filename, enum py_CompileMode mode, py_Ref module) {
+    return _py_exec(source, filename, mode, module, false);
+}
+
+bool py_execdynamic(const char* source,
+                    const char* filename,
+                    enum py_CompileMode mode,
+                    py_Ref module) {
+    return _py_exec(source, filename, mode, module, true);
+}
+
 bool py_call(py_Ref f, int argc, py_Ref argv) {
     if(f->type == tp_nativefunc) {
         return py_callcfunc(f->_cfunc, argc, argv);
@@ -120,8 +141,11 @@ bool py_callcfunc(py_CFunction f, int argc, py_Ref argv) {
     py_newnil(py_retval());
     bool ok = f(argc, argv);
     if(!ok) return false;
-    if(py_peek(0) != p0) c11__abort("py_CFunction corrupts the stack! Did you forget to call `py_pop()`?");
-    if(py_isnil(py_retval())) c11__abort("py_CFunction returns nothing! Did you forget to call `py_newnone(py_retval())`?");
+    if(py_peek(0) != p0)
+        c11__abort("py_CFunction corrupts the stack! Did you forget to call `py_pop()`?");
+    if(py_isnil(py_retval()))
+        c11__abort(
+            "py_CFunction returns nothing! Did you forget to call `py_newnone(py_retval())`?");
     return true;
 }