blueloveTH 1 rok temu
rodzic
commit
87bf0c9e7c
4 zmienionych plików z 83 dodań i 54 usunięć
  1. 5 4
      include/pocketpy/pocketpy.h
  2. 74 0
      src/public/exec.c
  3. 1 47
      src/public/internal.c
  4. 3 3
      src/public/stack_ops.c

+ 5 - 4
include/pocketpy/pocketpy.h

@@ -209,15 +209,16 @@ py_GlobalRef py_tpfindmagic(py_Type, py_Name name);
 /// Search the name from the given type to the base type.
 /// Return `NULL` if not found.
 py_GlobalRef py_tpfindname(py_Type, py_Name name);
+/// Get the magic method from the given type only.
+/// The returned reference is always valid. However, its value may be `nil`.
+py_GlobalRef py_tpgetmagic(py_Type type, py_Name name);
+
 /// Get the type object of the given type.
 py_GlobalRef py_tpobject(py_Type type);
 /// Get the type name.
 const char* py_tpname(py_Type type);
 /// Call a type to create a new instance.
 bool py_tpcall(py_Type type, int argc, py_Ref argv) PY_RAISE;
-/// Get the magic method from the given type only.
-/// The returned reference is always valid. However, its value may be `nil`.
-py_GlobalRef py_tpmagic(py_Type type, py_Name name);
 
 /// Check if the object is an instance of the given type.
 /// Raise `TypeError` if the check fails.
@@ -287,7 +288,7 @@ void py_bindfunc(py_Ref obj, const char* name, py_CFunction f);
 /// @param setter setter function. Use `NULL` if not needed.
 void py_bindproperty(py_Type type, const char* name, py_CFunction getter, py_CFunction setter);
 
-#define py_bindmagic(type, __magic__, f) py_newnativefunc(py_tpmagic((type), __magic__), (f))
+#define py_bindmagic(type, __magic__, f) py_newnativefunc(py_tpgetmagic((type), __magic__), (f))
 
 #define PY_CHECK_ARGC(n)                                                                           \
     if(argc != n) return TypeError("expected %d arguments, got %d", n, argc)

+ 74 - 0
src/public/exec.c

@@ -0,0 +1,74 @@
+#include "pocketpy/objects/codeobject.h"
+#include "pocketpy/objects/sourcedata.h"
+#include "pocketpy/pocketpy.h"
+
+#include "pocketpy/common/utils.h"
+#include "pocketpy/common/sstream.h"
+#include "pocketpy/objects/object.h"
+#include "pocketpy/interpreter/vm.h"
+#include "pocketpy/compiler/compiler.h"
+
+typedef struct {
+    const char* source;
+    const char* filename;
+    int mode;
+    int is_dynamic;
+} py_ExecKey;
+
+static int py_ExecKey__cmp(const py_ExecKey* a, const py_ExecKey* b) {
+    return memcmp(a, b, sizeof(py_ExecKey));
+}
+
+static void py_ExecKey__ctor(py_ExecKey* key, const char* source, const char* filename,
+                             enum py_CompileMode mode, bool is_dynamic) {
+    key->source = source;
+    key->filename = filename;
+    key->mode = mode;
+    key->is_dynamic = is_dynamic;
+}
+
+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;
+    // py_ExecKey cache_key;
+    // py_ExecKey__ctor(&cache_key, source, filename, mode, is_dynamic);
+    CodeObject co;
+    SourceData_ src = SourceData__rcnew(source, filename, mode, is_dynamic);
+    Error* err = pk_compile(src, &co);
+    if(err) {
+        py_exception(tp_SyntaxError, err->msg);
+        py_BaseException__stpush(&vm->curr_exception, src, err->lineno, NULL);
+
+        PK_DECREF(src);
+        free(err);
+        return false;
+    }
+
+    if(!module) module = &vm->main;
+
+    py_StackRef sp = vm->stack.sp;
+    if(is_dynamic) {
+        // [globals, locals]
+        sp -= 2;
+    }
+
+    Frame* frame = Frame__new(&co, module, sp, sp, false, is_dynamic);
+    VM__push_frame(vm, frame);
+    FrameResult res = VM__run_top_frame(vm);
+    CodeObject__dtor(&co);
+    PK_DECREF(src);
+    if(res == RES_ERROR) return false;
+    if(res == RES_RETURN) return true;
+    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_execdyn(const char* source, const char* filename, enum py_CompileMode mode, py_Ref module) {
+    return _py_exec(source, filename, mode, module, true);
+}

+ 1 - 47
src/public/internal.c

@@ -7,8 +7,6 @@
 #include "pocketpy/objects/object.h"
 #include "pocketpy/interpreter/vm.h"
 #include "pocketpy/compiler/compiler.h"
-#include <stdbool.h>
-#include <stdint.h>
 
 VM* pk_current_vm;
 
@@ -78,50 +76,6 @@ const char* pk_opname(Opcode op) {
     return OP_NAMES[op];
 }
 
-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, is_dynamic);
-    Error* err = pk_compile(src, &co);
-    if(err) {
-        py_exception(tp_SyntaxError, err->msg);
-        py_BaseException__stpush(&vm->curr_exception, src, err->lineno, NULL);
-
-        PK_DECREF(src);
-        free(err);
-        return false;
-    }
-
-    if(!module) module = &vm->main;
-
-    py_StackRef sp = vm->stack.sp;
-    if(is_dynamic) {
-        // [globals, locals]
-        sp -= 2;
-    }
-
-    Frame* frame = Frame__new(&co, module, sp, sp, false, is_dynamic);
-    VM__push_frame(vm, frame);
-    FrameResult res = VM__run_top_frame(vm);
-    CodeObject__dtor(&co);
-    PK_DECREF(src);
-    if(res == RES_ERROR) return false;
-    if(res == RES_RETURN) return true;
-    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_execdyn(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);
@@ -220,7 +174,7 @@ py_Ref py_tpfindname(py_Type t, py_Name name) {
     return NULL;
 }
 
-py_Ref py_tpmagic(py_Type type, py_Name name) {
+py_Ref py_tpgetmagic(py_Type type, py_Name name) {
     assert(py_ismagicname(name));
     VM* vm = pk_current_vm;
     return &c11__at(py_TypeInfo, &vm->types, type)->magic[name];

+ 3 - 3
src/public/stack_ops.c

@@ -14,7 +14,7 @@ py_Ref py_getdict(py_Ref self, py_Name name) {
         return NameDict__try_get(PyObject__dict(self->_obj), name);
     } else {
         py_Type* ud = py_touserdata(self);
-        py_Ref slot = py_tpmagic(*ud, name);
+        py_Ref slot = py_tpgetmagic(*ud, name);
         return py_isnil(slot) ? NULL : slot;
     }
 }
@@ -25,7 +25,7 @@ void py_setdict(py_Ref self, py_Name name, py_Ref val) {
         NameDict__set(PyObject__dict(self->_obj), name, *val);
     } else {
         py_Type* ud = py_touserdata(self);
-        *py_tpmagic(*ud, name) = *val;
+        *py_tpgetmagic(*ud, name) = *val;
     }
 }
 
@@ -41,7 +41,7 @@ bool py_deldict(py_Ref self, py_Name name) {
 
     } else {
         py_Type* ud = py_touserdata(self);
-        py_newnil(py_tpmagic(*ud, name));
+        py_newnil(py_tpgetmagic(*ud, name));
         return true;
     }
 }