mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 19:40:18 +00:00
up
up up
This commit is contained in:
parent
ca07bd7394
commit
74ed211f7b
@ -9,7 +9,7 @@ struct Frame {
|
|||||||
int _ip = -1;
|
int _ip = -1;
|
||||||
int _next_ip = 0;
|
int _next_ip = 0;
|
||||||
|
|
||||||
const CodeObject_ co;
|
const CodeObject* co;
|
||||||
PyVar _module;
|
PyVar _module;
|
||||||
pkpy::shared_ptr<pkpy::NameDict> _locals;
|
pkpy::shared_ptr<pkpy::NameDict> _locals;
|
||||||
pkpy::shared_ptr<pkpy::NameDict> _closure;
|
pkpy::shared_ptr<pkpy::NameDict> _closure;
|
||||||
@ -24,9 +24,9 @@ struct Frame {
|
|||||||
return _closure->try_get(name);
|
return _closure->try_get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Frame(const CodeObject_ co, PyVar _module,
|
Frame(const CodeObject_& co, const PyVar& _module,
|
||||||
pkpy::shared_ptr<pkpy::NameDict> _locals=nullptr, pkpy::shared_ptr<pkpy::NameDict> _closure=nullptr)
|
pkpy::shared_ptr<pkpy::NameDict> _locals=nullptr, pkpy::shared_ptr<pkpy::NameDict> _closure=nullptr)
|
||||||
: co(co), _module(_module), _locals(_locals), _closure(_closure), id(kFrameGlobalId++) { }
|
: co(co.get()), _module(_module), _locals(_locals), _closure(_closure), id(kFrameGlobalId++) { }
|
||||||
|
|
||||||
inline const Bytecode& next_bytecode() {
|
inline const Bytecode& next_bytecode() {
|
||||||
_ip = _next_ip++;
|
_ip = _next_ip++;
|
||||||
|
@ -80,7 +80,7 @@ namespace pkpy{
|
|||||||
return reinterpret_cast<__VAL>(counter);
|
return reinterpret_cast<__VAL>(counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool is_tagged() const {
|
inline constexpr bool is_tagged() const {
|
||||||
if constexpr(!std::is_same_v<T, PyObject>) return false;
|
if constexpr(!std::is_same_v<T, PyObject>) return false;
|
||||||
return (reinterpret_cast<i64>(counter) & 0b11) != 0b00;
|
return (reinterpret_cast<i64>(counter) & 0b11) != 0b00;
|
||||||
}
|
}
|
||||||
|
@ -36,8 +36,8 @@ namespace pkpy{
|
|||||||
|
|
||||||
int size() const { return _size; }
|
int size() const { return _size; }
|
||||||
|
|
||||||
//https://github.com/python/cpython/blob/main/Objects/dictobject.c#L175
|
//https://github.com/python/cpython/blob/main/Objects/dictobject.c#L175
|
||||||
#define HASH_PROBE(key, ok, i) \
|
#define HASH_PROBE(key, ok, i) \
|
||||||
int i = (key).index % _capacity; \
|
int i = (key).index % _capacity; \
|
||||||
bool ok = false; \
|
bool ok = false; \
|
||||||
while(!_a[i].empty()) { \
|
while(!_a[i].empty()) { \
|
||||||
@ -45,7 +45,7 @@ namespace pkpy{
|
|||||||
i = (5*i + 1) % _capacity; \
|
i = (5*i + 1) % _capacity; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HASH_PROBE_OVERRIDE(key, ok, i) \
|
#define HASH_PROBE_OVERRIDE(key, ok, i) \
|
||||||
i = (key).index % _capacity; \
|
i = (key).index % _capacity; \
|
||||||
ok = false; \
|
ok = false; \
|
||||||
while(!_a[i].empty()) { \
|
while(!_a[i].empty()) { \
|
||||||
@ -95,6 +95,13 @@ namespace pkpy{
|
|||||||
return &_a[i].second;
|
return &_a[i].second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool try_set(StrName key, PyVar&& value){
|
||||||
|
HASH_PROBE(key, ok, i);
|
||||||
|
if(!ok) return false;
|
||||||
|
_a[i].second = std::move(value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool contains(StrName key) const {
|
inline bool contains(StrName key) const {
|
||||||
HASH_PROBE(key, ok, i);
|
HASH_PROBE(key, ok, i);
|
||||||
return ok;
|
return ok;
|
||||||
|
@ -20,7 +20,7 @@ struct NameRef : BaseRef {
|
|||||||
const std::pair<StrName, NameScope> pair;
|
const std::pair<StrName, NameScope> pair;
|
||||||
inline StrName name() const { return pair.first; }
|
inline StrName name() const { return pair.first; }
|
||||||
inline NameScope scope() const { return pair.second; }
|
inline NameScope scope() const { return pair.second; }
|
||||||
NameRef(std::pair<StrName, NameScope>& pair) : pair(pair) {}
|
NameRef(const std::pair<StrName, NameScope>& pair) : pair(pair) {}
|
||||||
|
|
||||||
PyVar get(VM* vm, Frame* frame) const;
|
PyVar get(VM* vm, Frame* frame) const;
|
||||||
void set(VM* vm, Frame* frame, PyVar val) const;
|
void set(VM* vm, Frame* frame, PyVar val) const;
|
||||||
|
34
src/vm.h
34
src/vm.h
@ -151,30 +151,29 @@ public:
|
|||||||
return f(this, args);
|
return f(this, args);
|
||||||
} else if(is_type(*callable, tp_function)){
|
} else if(is_type(*callable, tp_function)){
|
||||||
const pkpy::Function& fn = PyFunction_AS_C(*callable);
|
const pkpy::Function& fn = PyFunction_AS_C(*callable);
|
||||||
auto _locals = pkpy::make_shared<pkpy::NameDict>(
|
auto locals = pkpy::make_shared<pkpy::NameDict>(
|
||||||
fn.code->ideal_locals_capacity, kLocalsLoadFactor
|
fn.code->ideal_locals_capacity, kLocalsLoadFactor
|
||||||
);
|
);
|
||||||
pkpy::NameDict& locals = *_locals;
|
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(StrName name : fn.args){
|
for(StrName name : fn.args){
|
||||||
if(i < args.size()){
|
if(i < args.size()){
|
||||||
locals.emplace(name, args[i++]);
|
locals->emplace(name, args[i++]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
TypeError("missing positional argument " + name.str().escape(true));
|
TypeError("missing positional argument " + name.str().escape(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
locals.insert(fn.kwargs.begin(), fn.kwargs.end());
|
locals->insert(fn.kwargs.begin(), fn.kwargs.end());
|
||||||
|
|
||||||
if(!fn.starred_arg.empty()){
|
if(!fn.starred_arg.empty()){
|
||||||
pkpy::List vargs; // handle *args
|
pkpy::List vargs; // handle *args
|
||||||
while(i < args.size()) vargs.push_back(args[i++]);
|
while(i < args.size()) vargs.push_back(args[i++]);
|
||||||
locals.emplace(fn.starred_arg, PyTuple(std::move(vargs)));
|
locals->emplace(fn.starred_arg, PyTuple(std::move(vargs)));
|
||||||
}else{
|
}else{
|
||||||
for(StrName key : fn.kwargs_order){
|
for(StrName key : fn.kwargs_order){
|
||||||
if(i < args.size()){
|
if(i < args.size()){
|
||||||
locals.emplace(key, args[i++]);
|
locals->emplace(key, args[i++]);
|
||||||
}else{
|
}else{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -187,10 +186,10 @@ public:
|
|||||||
if(!fn.kwargs.contains(key)){
|
if(!fn.kwargs.contains(key)){
|
||||||
TypeError(key.escape(true) + " is an invalid keyword argument for " + fn.name + "()");
|
TypeError(key.escape(true) + " is an invalid keyword argument for " + fn.name + "()");
|
||||||
}
|
}
|
||||||
locals.emplace(key, kwargs[i+1]);
|
locals->emplace(key, kwargs[i+1]);
|
||||||
}
|
}
|
||||||
PyVar _module = fn._module != nullptr ? fn._module : top_frame()->_module;
|
const PyVar& _module = fn._module != nullptr ? fn._module : top_frame()->_module;
|
||||||
auto _frame = _new_frame(fn.code, _module, _locals, fn._closure);
|
auto _frame = _new_frame(fn.code, _module, locals, fn._closure);
|
||||||
if(fn.code->is_generator){
|
if(fn.code->is_generator){
|
||||||
return PyIter(pkpy::make_shared<BaseIter, Generator>(
|
return PyIter(pkpy::make_shared<BaseIter, Generator>(
|
||||||
this, std::move(_frame)));
|
this, std::move(_frame)));
|
||||||
@ -742,13 +741,13 @@ public:
|
|||||||
PyVar NameRef::get(VM* vm, Frame* frame) const{
|
PyVar NameRef::get(VM* vm, Frame* frame) const{
|
||||||
PyVar* val;
|
PyVar* val;
|
||||||
val = frame->f_locals().try_get(name());
|
val = frame->f_locals().try_get(name());
|
||||||
if(val) return *val;
|
if(val != nullptr) return *val;
|
||||||
val = frame->f_closure_try_get(name());
|
val = frame->f_closure_try_get(name());
|
||||||
if(val) return *val;
|
if(val != nullptr) return *val;
|
||||||
val = frame->f_globals().try_get(name());
|
val = frame->f_globals().try_get(name());
|
||||||
if(val) return *val;
|
if(val != nullptr) return *val;
|
||||||
val = vm->builtins->attr().try_get(name());
|
val = vm->builtins->attr().try_get(name());
|
||||||
if(val) return *val;
|
if(val != nullptr) return *val;
|
||||||
vm->NameError(name());
|
vm->NameError(name());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -757,14 +756,9 @@ void NameRef::set(VM* vm, Frame* frame, PyVar val) const{
|
|||||||
switch(scope()) {
|
switch(scope()) {
|
||||||
case NAME_LOCAL: frame->f_locals()[name()] = std::move(val); break;
|
case NAME_LOCAL: frame->f_locals()[name()] = std::move(val); break;
|
||||||
case NAME_GLOBAL:
|
case NAME_GLOBAL:
|
||||||
{
|
if(frame->f_locals().try_set(name(), std::move(val))) return;
|
||||||
PyVar* existing = frame->f_locals().try_get(name());
|
|
||||||
if(existing != nullptr){
|
|
||||||
*existing = std::move(val);
|
|
||||||
}else{
|
|
||||||
frame->f_globals()[name()] = std::move(val);
|
frame->f_globals()[name()] = std::move(val);
|
||||||
}
|
break;
|
||||||
} break;
|
|
||||||
default: UNREACHABLE();
|
default: UNREACHABLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user