This commit is contained in:
blueloveTH 2024-08-09 13:40:02 +08:00
parent a96173fd6a
commit 87bf0c9e7c
4 changed files with 83 additions and 54 deletions

View File

@ -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
src/public/exec.c Normal file
View File

@ -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);
}

View File

@ -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];

View File

@ -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;
}
}