mirror of
				https://github.com/pocketpy/pocketpy
				synced 2025-10-31 00:40:16 +00:00 
			
		
		
		
	Compare commits
	
		
			No commits in common. "8ae999ecdff55fa18359950082a1a4982ad83396" and "841cc25a4eaf77ec64885a24bd24e8baacccb1dc" have entirely different histories.
		
	
	
		
			8ae999ecdf
			...
			841cc25a4e
		
	
		
| @ -11,7 +11,7 @@ | ||||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| typedef struct c11_array { | ||||
| typedef struct c11_array{ | ||||
|     void* data; | ||||
|     int count; | ||||
|     int elem_size; | ||||
| @ -21,7 +21,7 @@ void c11_array__ctor(c11_array* self, int elem_size, int count); | ||||
| void c11_array__dtor(c11_array* self); | ||||
| c11_array c11_array__copy(const c11_array* self); | ||||
| 
 | ||||
| typedef struct c11_vector { | ||||
| typedef struct c11_vector{ | ||||
|     void* data; | ||||
|     int count; | ||||
|     int capacity; | ||||
| @ -40,57 +40,54 @@ c11_array c11_vector__submit(c11_vector* self); | ||||
| #define c11__setitem(T, self, index, value) ((T*)(self)->data)[index] = value; | ||||
| #define c11__at(T, self, index) ((T*)(self)->data + index) | ||||
| 
 | ||||
| #define c11_vector__push(T, self, elem)                                                            \ | ||||
|     do {                                                                                           \ | ||||
|         if((self)->count == (self)->capacity) c11_vector__reserve((self), (self)->capacity * 2);   \ | ||||
|         ((T*)(self)->data)[(self)->count] = (elem);                                                \ | ||||
|         (self)->count++;                                                                           \ | ||||
|     } while(0) | ||||
| #define c11_vector__push(T, self, elem) \ | ||||
|     do{ \ | ||||
|         if((self)->count == (self)->capacity) c11_vector__reserve((self), (self)->capacity*2); \ | ||||
|         ((T*)(self)->data)[(self)->count] = (elem); \ | ||||
|         (self)->count++; \ | ||||
|     }while(0) | ||||
| 
 | ||||
| #define c11_vector__pop(self) (--(self)->count) | ||||
| 
 | ||||
| #define c11_vector__back(T, self) (((T*)(self)->data)[(self)->count - 1]) | ||||
| #define c11_vector__back(T, self) \ | ||||
|     (((T*)(self)->data)[(self)->count - 1]) | ||||
| 
 | ||||
| #define c11_vector__extend(T, self, p, size)                                                       \ | ||||
|     do {                                                                                           \ | ||||
|         c11_vector__reserve((self), (self)->count + (size));                                       \ | ||||
|         memcpy((T*)(self)->data + (self)->count, (p), (size) * sizeof(T));                         \ | ||||
|         (self)->count += (size);                                                                   \ | ||||
|     } while(0) | ||||
| 
 | ||||
| #define c11_vector__insert(T, self, index, elem)                                                   \ | ||||
|     do {                                                                                           \ | ||||
|         if((self)->count == (self)->capacity) c11_vector__reserve((self), (self)->capacity * 2);   \ | ||||
|         T* p = (T*)(self)->data + (index);                                                         \ | ||||
|         memmove(p + 1, p, ((self)->count - (index)) * sizeof(T));                                  \ | ||||
|         *p = (elem);                                                                               \ | ||||
|         (self)->count++;                                                                           \ | ||||
|     } while(0) | ||||
| 
 | ||||
| #define c11_vector__erase(T, self, index)                                                          \ | ||||
|     do {                                                                                           \ | ||||
|         T* p = (T*)(self)->data + (index);                                                         \ | ||||
|         memmove(p, p + 1, ((self)->count - (index)-1) * sizeof(T));                                \ | ||||
|         (self)->count--;                                                                           \ | ||||
|     } while(0) | ||||
| 
 | ||||
| #define c11_vector__reverse(T, self, start, end)                                                   \ | ||||
|     do {                                                                                           \ | ||||
|         T* p = (T*)(self)->data + (start);                                                         \ | ||||
|         T* q = (T*)(self)->data + (end);                                                           \ | ||||
|         while(p < q) {                                                                             \ | ||||
|             T tmp = *p;                                                                            \ | ||||
|             *p = *q;                                                                               \ | ||||
|             *q = tmp;                                                                              \ | ||||
|             p++;                                                                                   \ | ||||
|             q--;                                                                                   \ | ||||
|         }                                                                                          \ | ||||
|     } while(0) | ||||
| #define c11_vector__extend(T, self, p, size) \ | ||||
|     do{ \ | ||||
|         c11_vector__reserve((self), (self)->count + (size)); \ | ||||
|         memcpy((T*)(self)->data + (self)->count, (p), (size) * sizeof(T)); \ | ||||
|         (self)->count += (size); \ | ||||
|     }while(0) | ||||
| 
 | ||||
| 
 | ||||
| // NOTE: here we do an extra NULL check for it to avoid UB
 | ||||
| #define c11__foreach(T, self, it)                                                                  \ | ||||
|     for(T* it = (self)->data; it && it != (T*)(self)->data + (self)->count; it++) | ||||
| #define c11_vector__insert(T, self, index, elem) \ | ||||
|     do{ \ | ||||
|         if((self)->count == (self)->capacity) c11_vector__reserve((self), (self)->capacity*2); \ | ||||
|         T* p = (T*)(self)->data + (index); \ | ||||
|         memmove(p + 1, p, ((self)->count - (index)) * sizeof(T)); \ | ||||
|         *p = (elem); \ | ||||
|         (self)->count++; \ | ||||
|     }while(0) | ||||
| 
 | ||||
| #define c11_vector__erase(T, self, index) \ | ||||
|     do{ \ | ||||
|         T* p = (T*)(self)->data + (index); \ | ||||
|         memmove(p, p + 1, ((self)->count - (index) - 1) * sizeof(T)); \ | ||||
|         (self)->count--; \ | ||||
|     }while(0) | ||||
| 
 | ||||
| #define c11_vector__reverse(T, self, start, end) \ | ||||
|     do{ \ | ||||
|         T* p = (T*)(self)->data + (start); \ | ||||
|         T* q = (T*)(self)->data + (end); \ | ||||
|         while(p < q){ \ | ||||
|             T tmp = *p; *p = *q; *q = tmp; \ | ||||
|             p++; q--; \ | ||||
|         } \ | ||||
|     }while(0) | ||||
| 
 | ||||
| #define c11__foreach(T, self, it) \ | ||||
|     for(T* it = (T*)(self)->data; it != (T*)(self)->data + (self)->count; it++) | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
|  | ||||
| @ -87,8 +87,6 @@ py_Type pk_VM__new_type(pk_VM* self, | ||||
|                         const py_TValue* module, | ||||
|                         bool subclass_enabled); | ||||
| 
 | ||||
| pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t argc, uint16_t kwargc, bool opcall); | ||||
| 
 | ||||
| // type registration
 | ||||
| py_Type pk_str__register(); | ||||
| py_Type pk_bytes__register(); | ||||
|  | ||||
| @ -128,11 +128,11 @@ py_GlobalRef py_tpmagic(py_Type type, py_Name name); | ||||
| // new style decl-based bindings
 | ||||
| py_TmpRef py_bind(py_Ref obj, const char* sig, py_CFunction f); | ||||
| py_TmpRef py_bind2(py_Ref obj, | ||||
|                    const char* sig, | ||||
|                    py_CFunction f, | ||||
|                    BindType bt, | ||||
|                    const char* docstring, | ||||
|                    const py_Ref upvalue); | ||||
|                 const char* sig, | ||||
|                 py_CFunction f, | ||||
|                 BindType bt, | ||||
|                 const char* docstring, | ||||
|                 const py_Ref upvalue); | ||||
| // old style argc-based bindings
 | ||||
| void py_bindmethod(py_Type type, const char* name, py_CFunction f); | ||||
| void py_bindmethod2(py_Type type, const char* name, py_CFunction f, BindType bt); | ||||
| @ -253,7 +253,7 @@ bool py_isidentical(const py_Ref, const py_Ref); | ||||
| /// It assumes `argc + kwargc` arguments are already pushed to the stack.
 | ||||
| /// The result will be set to `py_retval()`.
 | ||||
| /// The stack size will be reduced by `argc + kwargc`.
 | ||||
| bool py_vectorcall(uint16_t argc, uint16_t kwargc); | ||||
| bool pk_vectorcall(int argc, int kwargc, bool op_call); | ||||
| /// Call a function.
 | ||||
| /// It prepares the stack and then performs a `vectorcall(argc, 0, false)`.
 | ||||
| /// The result will be set to `py_retval()`.
 | ||||
| @ -323,43 +323,26 @@ bool py_checktype(const py_Ref self, py_Type type); | ||||
| /// %t: py_Type
 | ||||
| /// %n: py_Name
 | ||||
| 
 | ||||
| enum py_MagicNames { | ||||
|     py_MagicNames__NULL,  // 0 is reserved
 | ||||
| 
 | ||||
| #define MAGIC_METHOD(x) x, | ||||
| #include "pocketpy/xmacros/magics.h" | ||||
| #undef MAGIC_METHOD | ||||
| enum py_MagicNames{ | ||||
|     py_MagicNames__NULL,  // 0 is reserved
 | ||||
|     #define MAGIC_METHOD(x) x, | ||||
|     #include "pocketpy/xmacros/magics.h" | ||||
|     #undef MAGIC_METHOD | ||||
| }; | ||||
| 
 | ||||
| enum py_PredefinedTypes { | ||||
|     tp_object = 1, | ||||
|     tp_type, | ||||
|     tp_int, | ||||
|     tp_float, | ||||
|     tp_bool, | ||||
|     tp_str, | ||||
|     tp_list, | ||||
|     tp_tuple, | ||||
|     tp_slice, | ||||
|     tp_range, | ||||
|     tp_module, | ||||
|     tp_function, | ||||
|     tp_nativefunc, | ||||
|     tp_bound_method, | ||||
|     tp_super, | ||||
|     tp_exception, | ||||
|     tp_bytes, | ||||
|     tp_mappingproxy, | ||||
|     tp_dict, | ||||
|     tp_property, | ||||
|     tp_star_wrapper, | ||||
|     tp_staticmethod, | ||||
|     tp_classmethod, | ||||
|     tp_none_type, | ||||
|     tp_not_implemented_type, | ||||
| enum py_PredefinedTypes{ | ||||
|     tp_object = 1, tp_type, | ||||
|     tp_int, tp_float, tp_bool, tp_str, | ||||
|     tp_list, tp_tuple, | ||||
|     tp_slice, tp_range, tp_module, | ||||
|     tp_function, tp_nativefunc, tp_bound_method, | ||||
|     tp_super, tp_exception, tp_bytes, tp_mappingproxy, | ||||
|     tp_dict, tp_property, tp_star_wrapper, | ||||
|     tp_staticmethod, tp_classmethod, | ||||
|     tp_none_type, tp_not_implemented_type, | ||||
|     tp_ellipsis, | ||||
|     tp_syntax_error, | ||||
|     tp_stop_iteration | ||||
|     tp_syntax_error, tp_stop_iteration | ||||
| }; | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
|  | ||||
| @ -48,8 +48,8 @@ c11_vector c11_vector__copy(const c11_vector* self){ | ||||
| void c11_vector__reserve(c11_vector* self, int capacity){ | ||||
|     if(capacity < 4) capacity = 4; | ||||
|     if(capacity <= self->capacity) return; | ||||
|     self->data = realloc(self->data, self->elem_size * capacity); | ||||
|     self->capacity = capacity; | ||||
|     self->data = realloc(self->data, self->elem_size * self->capacity); | ||||
| } | ||||
| 
 | ||||
| void c11_vector__clear(c11_vector* self){ | ||||
|  | ||||
| @ -3,7 +3,6 @@ | ||||
| #include "pocketpy/common/sstream.h" | ||||
| #include "pocketpy/objects/codeobject.h" | ||||
| #include "pocketpy/pocketpy.h" | ||||
| #include <stdbool.h> | ||||
| 
 | ||||
| int UnboundLocalError(py_Name name) { return -1; } | ||||
| 
 | ||||
| @ -49,9 +48,9 @@ static bool stack_binaryop(pk_VM* self, py_Name op, py_Name rop); | ||||
|         *SECOND() = *THIRD();                                                                      \ | ||||
|     } while(0) | ||||
| 
 | ||||
| #define vectorcall_opcall(argc, kwargc)                                                            \ | ||||
| #define vectorcall_opcall(n)                                                                       \ | ||||
|     do {                                                                                           \ | ||||
|         pk_FrameResult res = pk_VM__vectorcall(self, (argc), (kwargc), true);                                \ | ||||
|         pk_FrameResult res = pk_vectorcall(n, 0, true);                                            \ | ||||
|         switch(res) {                                                                              \ | ||||
|             case RES_RETURN: PUSH(&self->last_retval); break;                                      \ | ||||
|             case RES_CALL:                                                                         \ | ||||
| @ -269,7 +268,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) { | ||||
|                     } else { | ||||
|                         INSERT_THIRD();     // [?, a, b]
 | ||||
|                         *THIRD() = *magic;  // [__getitem__, a, b]
 | ||||
|                         vectorcall_opcall(2, 0); | ||||
|                         vectorcall_opcall(2); | ||||
|                     } | ||||
|                     DISPATCH(); | ||||
|                 } | ||||
| @ -322,7 +321,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) { | ||||
|                     } else { | ||||
|                         INSERT_THIRD();      // [?, a, b]
 | ||||
|                         *FOURTH() = *magic;  // [__selitem__, a, b, val]
 | ||||
|                         vectorcall_opcall(3, 0); | ||||
|                         vectorcall_opcall(3); | ||||
|                         POP();  // discard retval
 | ||||
|                     } | ||||
|                     DISPATCH(); | ||||
| @ -392,7 +391,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) { | ||||
|                     } else { | ||||
|                         INSERT_THIRD();     // [?, a, b]
 | ||||
|                         *THIRD() = *magic;  // [__delitem__, a, b]
 | ||||
|                         vectorcall_opcall(2, 0); | ||||
|                         vectorcall_opcall(2); | ||||
|                         POP();  // discard retval
 | ||||
|                     } | ||||
|                     DISPATCH(); | ||||
| @ -416,11 +415,11 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) { | ||||
|                 py_Ref f = py_getdict(&self->builtins, py_name("complex")); | ||||
|                 assert(f != NULL); | ||||
|                 py_TValue tmp = *TOP(); | ||||
|                 *TOP() = *f;              // [complex]
 | ||||
|                 py_newnull(SP()++);       // [complex, NULL]
 | ||||
|                 py_newint(SP()++, 0);     // [complex, NULL, 0]
 | ||||
|                 *SP()++ = tmp;            // [complex, NULL, 0, x]
 | ||||
|                 vectorcall_opcall(2, 0);  // [complex(x)]
 | ||||
|                 *TOP() = *f;           // [complex]
 | ||||
|                 py_newnull(SP()++);    // [complex, NULL]
 | ||||
|                 py_newint(SP()++, 0);  // [complex, NULL, 0]
 | ||||
|                 *SP()++ = tmp;         // [complex, NULL, 0, x]
 | ||||
|                 vectorcall_opcall(2);  // [complex(x)]
 | ||||
|                 DISPATCH(); | ||||
|             } | ||||
|             case OP_BUILD_BYTES: { | ||||
| @ -527,7 +526,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) { | ||||
|                     } else { | ||||
|                         INSERT_THIRD();     // [?, b, a]
 | ||||
|                         *THIRD() = *magic;  // [__contains__, a, b]
 | ||||
|                         vectorcall_opcall(2, 0); | ||||
|                         vectorcall_opcall(2); | ||||
|                     } | ||||
|                     bool res = py_tobool(TOP()); | ||||
|                     if(byte.arg) py_newbool(TOP(), !res); | ||||
| @ -605,19 +604,6 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) { | ||||
|                 //     DISPATCH_JUMP_ABSOLUTE(target)
 | ||||
|                 // }
 | ||||
|                 /*****************************************/ | ||||
|             case OP_FSTRING_EVAL: { | ||||
|                 assert(false); | ||||
|             } | ||||
|             case OP_REPR: { | ||||
|                 assert(false); | ||||
|             } | ||||
|             case OP_CALL: { | ||||
|                 pk_ManagedHeap__collect_if_needed(&self->heap); | ||||
|                 vectorcall_opcall(byte.arg & 0xFF, byte.arg >> 8); | ||||
|             } | ||||
|             case OP_CALL_VARGS: { | ||||
|                 assert(false); | ||||
|             } | ||||
|             case OP_RETURN_VALUE: { | ||||
|                 if(byte.arg == BC_NOARG) { | ||||
|                     self->last_retval = POPX(); | ||||
|  | ||||
| @ -98,13 +98,11 @@ static bool _py_number__pow__(int argc, py_Ref argv) { | ||||
|                 py_newfloat(py_retval(), pow(lhs, rhs)); | ||||
|             } | ||||
|         } else { | ||||
|             // rhs >= 0
 | ||||
|             int64_t ret = 1; | ||||
|             while(true){ | ||||
|             while(rhs) { | ||||
|                 if(rhs & 1) ret *= lhs; | ||||
|                 lhs *= lhs; | ||||
|                 rhs >>= 1; | ||||
|                 if(!rhs) break; | ||||
|                 lhs *= lhs;     // place this here to avoid overflow
 | ||||
|             } | ||||
|             py_newint(py_retval(), ret); | ||||
|         } | ||||
|  | ||||
| @ -1,13 +1,10 @@ | ||||
| #include "pocketpy/interpreter/vm.h" | ||||
| #include "pocketpy/common/memorypool.h" | ||||
| #include "pocketpy/common/sstream.h" | ||||
| #include "pocketpy/common/utils.h" | ||||
| #include "pocketpy/objects/base.h" | ||||
| #include "pocketpy/pocketpy.h" | ||||
| 
 | ||||
| #include <assert.h> | ||||
| #include <stdarg.h> | ||||
| #include <stdbool.h> | ||||
| 
 | ||||
| static unsigned char* pk_default_import_file(const char* path) { return NULL; } | ||||
| 
 | ||||
| @ -72,7 +69,7 @@ void pk_VM__ctor(pk_VM* self) { | ||||
| 
 | ||||
|     self->last_retval = PY_NULL; | ||||
|     self->has_error = false; | ||||
| 
 | ||||
|      | ||||
|     self->__curr_class = PY_NULL; | ||||
|     self->__cached_object_new = PY_NULL; | ||||
|     self->__dynamic_func_decl = NULL; | ||||
| @ -199,176 +196,6 @@ py_Type pk_VM__new_type(pk_VM* self, | ||||
|     return index; | ||||
| } | ||||
| 
 | ||||
| pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t ARGC, uint16_t KWARGC, bool opcall) { | ||||
|     py_Ref p1 = self->stack.sp - KWARGC * 2; | ||||
|     py_Ref p0 = p1 - ARGC - 2; | ||||
|     // [callable, <self>, args..., kwargs...]
 | ||||
|     //      ^p0                    ^p1      ^_sp
 | ||||
| 
 | ||||
|     // handle boundmethod, do a patch
 | ||||
|     if(p0->type == tp_bound_method) { | ||||
|         assert(false); | ||||
|         assert(py_isnull(p0+1));   // self must be NULL
 | ||||
|         // BoundMethod& bm = PK_OBJ_GET(BoundMethod, callable);
 | ||||
|         // callable = bm.func;  // get unbound method
 | ||||
|         // callable_t = _tp(callable);
 | ||||
|         // p1[-(ARGC + 2)] = bm.func;
 | ||||
|         // p1[-(ARGC + 1)] = bm.self;
 | ||||
|         // [unbound, self, args..., kwargs...]
 | ||||
|     } | ||||
| 
 | ||||
|     // PyVar* _base = args.begin();
 | ||||
|     py_Ref argv = py_isnull(p0+1) ? p0+2 : p0+1; | ||||
| 
 | ||||
| #if 0 | ||||
|     if(callable_t == tp_function) { | ||||
|         /*****************_py_call*****************/ | ||||
|         // check stack overflow
 | ||||
|         if(self->stack.sp > self->stack.end){ | ||||
|             StackOverflowError(); | ||||
|             return RES_ERROR; | ||||
|         } | ||||
| 
 | ||||
|         const Function& fn = PK_OBJ_GET(Function, callable); | ||||
|         const CodeObject* co = fn.decl->code; | ||||
| 
 | ||||
|         switch(fn.decl->type) { | ||||
|             case FuncType_NORMAL: | ||||
|                 __prepare_py_call(__vectorcall_buffer, args, kwargs, fn.decl); | ||||
|                 // copy buffer back to stack
 | ||||
|                 s_data.reset(_base + co->nlocals); | ||||
|                 for(int j = 0; j < co->nlocals; j++) | ||||
|                     _base[j] = __vectorcall_buffer[j]; | ||||
|                 break; | ||||
|             case FuncType_SIMPLE: | ||||
|                 if(args.size() != fn.decl->args.count) { | ||||
|                     TypeError(pk_format("{} takes {} positional arguments but {} were given", | ||||
|                                         &co->name, | ||||
|                                         fn.decl->args.count, | ||||
|                                         args.size())); | ||||
|                 } | ||||
|                 if(!kwargs.empty()) { | ||||
|                     TypeError(pk_format("{} takes no keyword arguments", &co->name)); | ||||
|                 } | ||||
|                 // [callable, <self>, args..., local_vars...]
 | ||||
|                 //      ^p0                    ^p1      ^_sp
 | ||||
|                 s_data.reset(_base + co->nlocals); | ||||
|                 // initialize local variables to PY_NULL
 | ||||
|                 std::memset(p1, 0, (char*)s_data._sp - (char*)p1); | ||||
|                 break; | ||||
|             case FuncType_EMPTY: | ||||
|                 if(args.size() != fn.decl->args.count) { | ||||
|                     TypeError(pk_format("{} takes {} positional arguments but {} were given", | ||||
|                                         &co->name, | ||||
|                                         fn.decl->args.count, | ||||
|                                         args.size())); | ||||
|                 } | ||||
|                 if(!kwargs.empty()) { | ||||
|                     TypeError(pk_format("{} takes no keyword arguments", &co->name)); | ||||
|                 } | ||||
|                 s_data.reset(p0); | ||||
|                 return None; | ||||
|             case FuncType_GENERATOR: | ||||
|                 __prepare_py_call(__vectorcall_buffer, args, kwargs, fn.decl); | ||||
|                 s_data.reset(p0); | ||||
|                 callstack.emplace(nullptr, co, fn._module, callable.get(), nullptr); | ||||
|                 return __py_generator( | ||||
|                     callstack.popx(), | ||||
|                     ArgsView(__vectorcall_buffer, __vectorcall_buffer + co->nlocals)); | ||||
|             default: PK_UNREACHABLE() | ||||
|         }; | ||||
| 
 | ||||
|         // simple or normal
 | ||||
|         callstack.emplace(p0, co, fn._module, callable.get(), args.begin()); | ||||
|         if(op_call) return pkpy_OP_CALL; | ||||
|         return __run_top_frame(); | ||||
|         /*****************_py_call*****************/ | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|     if(p0->type == tp_nativefunc) { | ||||
|         // const auto& f = PK_OBJ_GET(NativeFunc, callable);
 | ||||
|         // PyVar ret;
 | ||||
|         // if(f.decl != nullptr) {
 | ||||
|         //     int co_nlocals = f.decl->code->nlocals;
 | ||||
|         //     __prepare_py_call(__vectorcall_buffer, args, kwargs, f.decl);
 | ||||
|         //     // copy buffer back to stack
 | ||||
|         //     s_data.reset(_base + co_nlocals);
 | ||||
|         //     for(int j = 0; j < co_nlocals; j++)
 | ||||
|         //         _base[j] = __vectorcall_buffer[j];
 | ||||
|         //     ret = f.call(vm, ArgsView(s_data._sp - co_nlocals, s_data._sp));
 | ||||
|         // } else {
 | ||||
|         //     if(f.argc != -1) {
 | ||||
|         //         if(KWARGC != 0)
 | ||||
|         //             TypeError(
 | ||||
|         //                 "old-style native_func does not accept keyword arguments. If you want to skip this check, specify `argc` to -1");
 | ||||
|         //         if(args.size() != f.argc) {
 | ||||
|         //             vm->TypeError(_S("expected ", f.argc, " arguments, got ", args.size()));
 | ||||
|         //         }
 | ||||
|         //     }
 | ||||
|         //     ret = f.call(this, args);
 | ||||
|         // }
 | ||||
| 
 | ||||
|         if(!p0->_cfunc(ARGC, argv)) return RES_ERROR; | ||||
|         self->stack.sp = p0; | ||||
|         return RES_RETURN; | ||||
|     } | ||||
| 
 | ||||
| #if 0 | ||||
|     if(p0->type == tp_type) { | ||||
|         // [type, NULL, args..., kwargs...]
 | ||||
|         PyVar new_f = *find_name_in_mro(PK_OBJ_GET(Type, callable), __new__); | ||||
|         PyVar obj; | ||||
|         assert(new_f && (!p0[1])); | ||||
|         if(PyVar__IS_OP(&new_f, &__cached_object_new)) { | ||||
|             // fast path for object.__new__
 | ||||
|             obj = vm->new_object<DummyInstance>(PK_OBJ_GET(Type, callable)); | ||||
|         } else { | ||||
|             PUSH(new_f); | ||||
|             PUSH(PY_NULL); | ||||
|             PUSH(callable);  // cls
 | ||||
|             for(PyVar o: args) | ||||
|                 PUSH(o); | ||||
|             for(PyVar o: kwargs) | ||||
|                 PUSH(o); | ||||
|             // if obj is not an instance of `cls`, the behavior is undefined
 | ||||
|             obj = vectorcall(ARGC + 1, KWARGC); | ||||
|         } | ||||
| 
 | ||||
|         // __init__
 | ||||
|         PyVar self; | ||||
|         callable = get_unbound_method(obj, __init__, &self, false); | ||||
|         if(callable) { | ||||
|             callable_t = _tp(callable); | ||||
|             // replace `NULL` with `self`
 | ||||
|             p1[-(ARGC + 2)] = callable; | ||||
|             p1[-(ARGC + 1)] = self; | ||||
|             // [init_f, self, args..., kwargs...]
 | ||||
|             vectorcall(ARGC, KWARGC); | ||||
|             // We just discard the return value of `__init__`
 | ||||
|             // in cpython it raises a TypeError if the return value is not None
 | ||||
|         } else { | ||||
|             // manually reset the stack
 | ||||
|             s_data.reset(p0); | ||||
|         } | ||||
|         return obj; | ||||
|     } | ||||
| 
 | ||||
|     // handle `__call__` overload
 | ||||
|     PyVar self; | ||||
|     PyVar call_f = get_unbound_method(callable, __call__, &self, false); | ||||
|     if(self) { | ||||
|         p1[-(ARGC + 2)] = call_f; | ||||
|         p1[-(ARGC + 1)] = self; | ||||
|         // [call_f, self, args..., kwargs...]
 | ||||
|         return vectorcall(ARGC, KWARGC, op_call); | ||||
|     } | ||||
|     TypeError(_type_name(vm, callable_t).escape() + " object is not callable"); | ||||
| #endif | ||||
|      | ||||
|     PK_UNREACHABLE(); | ||||
| } | ||||
| 
 | ||||
| /****************************************/ | ||||
| void PyObject__delete(PyObject* self) { | ||||
|     pk_TypeInfo* ti = c11__at(pk_TypeInfo, &pk_current_vm->types, self->type); | ||||
| @ -394,4 +221,4 @@ void pk_ManagedHeap__mark(pk_ManagedHeap* self) { | ||||
|     // vm->obj_gc_mark(vm->__c.error);
 | ||||
|     // vm->__stack_gc_mark(vm->s_data.begin(), vm->s_data.end());
 | ||||
|     // if(self->_gc_marker_ex) self->_gc_marker_ex((pkpy_VM*)vm);
 | ||||
| } | ||||
| } | ||||
|  | ||||
| @ -6,7 +6,6 @@ | ||||
| #include "pocketpy/objects/object.h" | ||||
| #include "pocketpy/interpreter/vm.h" | ||||
| #include "pocketpy/compiler/compiler.h" | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| pk_VM* pk_current_vm; | ||||
| static pk_VM pk_default_vm; | ||||
| @ -68,14 +67,12 @@ static void disassemble(CodeObject* co) { | ||||
|         } | ||||
| 
 | ||||
|         char buf[32]; | ||||
|         snprintf(buf, sizeof(buf), "%-8s%-3s%-3d ", line, pointer, i); | ||||
|         snprintf(buf, sizeof(buf), "%-8s%-3s%-3d", line, pointer, i); | ||||
|         c11_sbuf__write_cstr(&ss, buf); | ||||
| 
 | ||||
|         c11_sbuf__write_cstr(&ss, OP_NAMES[byte.op]); | ||||
|         snprintf(buf, sizeof(buf), " %-24s", OP_NAMES[byte.op]); | ||||
|         c11_sbuf__write_cstr(&ss, buf); | ||||
|         c11_sbuf__write_char(&ss, ex.is_virtual ? '*' : ' '); | ||||
|         int padding = 24 - strlen(OP_NAMES[byte.op]); | ||||
|         for(int j = 0; j < padding; j++) | ||||
|             c11_sbuf__write_char(&ss, ' '); | ||||
| 
 | ||||
|         // _opcode_argstr(this, i, byte, co);
 | ||||
|         do { | ||||
| @ -184,10 +181,7 @@ bool py_call(py_Ref f, int argc, py_Ref argv) { return -1; } | ||||
| 
 | ||||
| bool py_callmethod(py_Ref self, py_Name name, int argc, py_Ref argv) { return -1; } | ||||
| 
 | ||||
| bool py_vectorcall(uint16_t argc, uint16_t kwargc) { | ||||
|     pk_VM* vm = pk_current_vm; | ||||
|     return pk_VM__vectorcall(vm, argc, kwargc, false) == RES_ERROR; | ||||
| } | ||||
| bool pk_vectorcall(int argc, int kwargc, bool op_call) { return -1; } | ||||
| 
 | ||||
| py_Ref py_retval() { return &pk_current_vm->last_retval; } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user