mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-21 12:00:18 +00:00
...
This commit is contained in:
parent
a96173fd6a
commit
87bf0c9e7c
@ -209,15 +209,16 @@ py_GlobalRef py_tpfindmagic(py_Type, py_Name name);
|
|||||||
/// Search the name from the given type to the base type.
|
/// Search the name from the given type to the base type.
|
||||||
/// Return `NULL` if not found.
|
/// Return `NULL` if not found.
|
||||||
py_GlobalRef py_tpfindname(py_Type, py_Name name);
|
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.
|
/// Get the type object of the given type.
|
||||||
py_GlobalRef py_tpobject(py_Type type);
|
py_GlobalRef py_tpobject(py_Type type);
|
||||||
/// Get the type name.
|
/// Get the type name.
|
||||||
const char* py_tpname(py_Type type);
|
const char* py_tpname(py_Type type);
|
||||||
/// Call a type to create a new instance.
|
/// Call a type to create a new instance.
|
||||||
bool py_tpcall(py_Type type, int argc, py_Ref argv) PY_RAISE;
|
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.
|
/// Check if the object is an instance of the given type.
|
||||||
/// Raise `TypeError` if the check fails.
|
/// 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.
|
/// @param setter setter function. Use `NULL` if not needed.
|
||||||
void py_bindproperty(py_Type type, const char* name, py_CFunction getter, py_CFunction setter);
|
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) \
|
#define PY_CHECK_ARGC(n) \
|
||||||
if(argc != n) return TypeError("expected %d arguments, got %d", n, argc)
|
if(argc != n) return TypeError("expected %d arguments, got %d", n, argc)
|
||||||
|
74
src/public/exec.c
Normal file
74
src/public/exec.c
Normal 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);
|
||||||
|
}
|
@ -7,8 +7,6 @@
|
|||||||
#include "pocketpy/objects/object.h"
|
#include "pocketpy/objects/object.h"
|
||||||
#include "pocketpy/interpreter/vm.h"
|
#include "pocketpy/interpreter/vm.h"
|
||||||
#include "pocketpy/compiler/compiler.h"
|
#include "pocketpy/compiler/compiler.h"
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
VM* pk_current_vm;
|
VM* pk_current_vm;
|
||||||
|
|
||||||
@ -78,50 +76,6 @@ const char* pk_opname(Opcode op) {
|
|||||||
return OP_NAMES[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) {
|
bool py_call(py_Ref f, int argc, py_Ref argv) {
|
||||||
if(f->type == tp_nativefunc) {
|
if(f->type == tp_nativefunc) {
|
||||||
return py_callcfunc(f->_cfunc, argc, argv);
|
return py_callcfunc(f->_cfunc, argc, argv);
|
||||||
@ -220,7 +174,7 @@ py_Ref py_tpfindname(py_Type t, py_Name name) {
|
|||||||
return NULL;
|
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));
|
assert(py_ismagicname(name));
|
||||||
VM* vm = pk_current_vm;
|
VM* vm = pk_current_vm;
|
||||||
return &c11__at(py_TypeInfo, &vm->types, type)->magic[name];
|
return &c11__at(py_TypeInfo, &vm->types, type)->magic[name];
|
||||||
|
@ -14,7 +14,7 @@ py_Ref py_getdict(py_Ref self, py_Name name) {
|
|||||||
return NameDict__try_get(PyObject__dict(self->_obj), name);
|
return NameDict__try_get(PyObject__dict(self->_obj), name);
|
||||||
} else {
|
} else {
|
||||||
py_Type* ud = py_touserdata(self);
|
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;
|
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);
|
NameDict__set(PyObject__dict(self->_obj), name, *val);
|
||||||
} else {
|
} else {
|
||||||
py_Type* ud = py_touserdata(self);
|
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 {
|
} else {
|
||||||
py_Type* ud = py_touserdata(self);
|
py_Type* ud = py_touserdata(self);
|
||||||
py_newnil(py_tpmagic(*ud, name));
|
py_newnil(py_tpgetmagic(*ud, name));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user