mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-21 03:50:16 +00:00
up
This commit is contained in:
parent
9077da4d6c
commit
66e6a6b559
14
src/ceval.h
14
src/ceval.h
@ -309,6 +309,20 @@ __NEXT_STEP:;
|
|||||||
}
|
}
|
||||||
}; DISPATCH();
|
}; DISPATCH();
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
|
case OP_UNPACK_SEQUENCE: {
|
||||||
|
// asIter or iter->next may run bytecode
|
||||||
|
// accidential gc may happen
|
||||||
|
// lock the gc via RAII
|
||||||
|
auto _lock = heap.gc_scope_lock();
|
||||||
|
PyObject* obj = asIter(frame->popx());
|
||||||
|
BaseIter* iter = PyIter_AS_C(obj);
|
||||||
|
for(int i=0; i<byte.arg; i++){
|
||||||
|
PyObject* item = iter->next();
|
||||||
|
if(item == nullptr) ValueError("not enough values to unpack");
|
||||||
|
frame->push(item);
|
||||||
|
}
|
||||||
|
if(iter->next() != nullptr) ValueError("too many values to unpack");
|
||||||
|
}; DISPATCH();
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
// case OP_SETUP_DECORATOR: DISPATCH();
|
// case OP_SETUP_DECORATOR: DISPATCH();
|
||||||
// case OP_BEGIN_CLASS: {
|
// case OP_BEGIN_CLASS: {
|
||||||
|
@ -40,7 +40,9 @@ class Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void pop_context(){
|
void pop_context(){
|
||||||
if(!ctx()->s_expr.empty()) UNREACHABLE();
|
if(!ctx()->s_expr.empty()){
|
||||||
|
throw std::runtime_error("!ctx()->s_expr.empty()\n" + ctx()->_log_s_expr());
|
||||||
|
}
|
||||||
// if the last op does not return, add a default return None
|
// if the last op does not return, add a default return None
|
||||||
if(ctx()->co->codes.empty() || ctx()->co->codes.back().op != OP_RETURN_VALUE){
|
if(ctx()->co->codes.empty() || ctx()->co->codes.back().op != OP_RETURN_VALUE){
|
||||||
ctx()->emit(OP_LOAD_NONE, BC_NOARG, BC_KEEPLINE);
|
ctx()->emit(OP_LOAD_NONE, BC_NOARG, BC_KEEPLINE);
|
||||||
@ -184,6 +186,7 @@ class Compiler {
|
|||||||
// PASS
|
// PASS
|
||||||
void exprTuple(){
|
void exprTuple(){
|
||||||
std::vector<Expr_> items;
|
std::vector<Expr_> items;
|
||||||
|
items.push_back(ctx()->s_expr.popx());
|
||||||
do {
|
do {
|
||||||
EXPR(); // NOTE: "1," will fail, "1,2" will be ok
|
EXPR(); // NOTE: "1," will fail, "1,2" will be ok
|
||||||
items.push_back(ctx()->s_expr.popx());
|
items.push_back(ctx()->s_expr.popx());
|
||||||
@ -385,6 +388,7 @@ class Compiler {
|
|||||||
// PASS
|
// PASS
|
||||||
void exprSubscr() {
|
void exprSubscr() {
|
||||||
auto e = make_expr<SubscrExpr>();
|
auto e = make_expr<SubscrExpr>();
|
||||||
|
e->a = ctx()->s_expr.popx();
|
||||||
std::vector<Expr_> items;
|
std::vector<Expr_> items;
|
||||||
do {
|
do {
|
||||||
EXPR_TUPLE();
|
EXPR_TUPLE();
|
||||||
@ -605,6 +609,7 @@ class Compiler {
|
|||||||
break;
|
break;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
|
std::cout << ctx()->_log_s_expr() << std::endl;
|
||||||
Expr_ rhs = ctx()->s_expr.popx();
|
Expr_ rhs = ctx()->s_expr.popx();
|
||||||
rhs->emit(ctx());
|
rhs->emit(ctx());
|
||||||
bool ok = lhs_p->emit_store(ctx());
|
bool ok = lhs_p->emit_store(ctx());
|
||||||
|
18
src/expr.h
18
src/expr.h
@ -5,6 +5,7 @@
|
|||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "ceval.h"
|
#include "ceval.h"
|
||||||
|
#include "str.h"
|
||||||
|
|
||||||
namespace pkpy{
|
namespace pkpy{
|
||||||
|
|
||||||
@ -55,11 +56,19 @@ struct CodeEmitContext{
|
|||||||
|
|
||||||
// clear the expression stack and generate bytecode
|
// clear the expression stack and generate bytecode
|
||||||
void emit_expr(){
|
void emit_expr(){
|
||||||
if(s_expr.size() != 1) UNREACHABLE();
|
if(s_expr.size() != 1){
|
||||||
|
throw std::runtime_error("s_expr.size() != 1\n" + _log_s_expr());
|
||||||
|
}
|
||||||
Expr_ expr = s_expr.popx();
|
Expr_ expr = s_expr.popx();
|
||||||
expr->emit(this);
|
expr->emit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Str _log_s_expr(){
|
||||||
|
StrStream ss;
|
||||||
|
for(auto& e: s_expr.data()) ss << e->str() << " ";
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
int emit(Opcode opcode, int arg, int line) {
|
int emit(Opcode opcode, int arg, int line) {
|
||||||
co->codes.push_back(
|
co->codes.push_back(
|
||||||
Bytecode{(uint16_t)opcode, (uint16_t)curr_block_i, arg, line}
|
Bytecode{(uint16_t)opcode, (uint16_t)curr_block_i, arg, line}
|
||||||
@ -411,8 +420,9 @@ struct TupleExpr: SequenceExpr{
|
|||||||
if(starred_i != items.size()-1) return false;
|
if(starred_i != items.size()-1) return false;
|
||||||
ctx->emit(OP_UNPACK_EX, items.size()-1, line);
|
ctx->emit(OP_UNPACK_EX, items.size()-1, line);
|
||||||
}
|
}
|
||||||
for(auto& e: items){
|
// do reverse emit
|
||||||
bool ok = e->emit_store(ctx);
|
for(int i=items.size()-1; i>=0; i--){
|
||||||
|
bool ok = items[i]->emit_store(ctx);
|
||||||
if(!ok) return false;
|
if(!ok) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -480,7 +490,7 @@ struct LambdaExpr: Expr{
|
|||||||
FuncDecl_ decl;
|
FuncDecl_ decl;
|
||||||
NameScope scope;
|
NameScope scope;
|
||||||
Str str() const override { return "<lambda>"; }
|
Str str() const override { return "<lambda>"; }
|
||||||
|
|
||||||
LambdaExpr(NameScope scope){
|
LambdaExpr(NameScope scope){
|
||||||
this->decl = make_sp<FuncDecl>();
|
this->decl = make_sp<FuncDecl>();
|
||||||
this->decl->name = "<lambda>";
|
this->decl->name = "<lambda>";
|
||||||
|
19
src/gc.h
19
src/gc.h
@ -47,6 +47,23 @@ struct ManagedHeap{
|
|||||||
int gc_threshold = kMinGCThreshold;
|
int gc_threshold = kMinGCThreshold;
|
||||||
int gc_counter = 0;
|
int gc_counter = 0;
|
||||||
|
|
||||||
|
/********************/
|
||||||
|
int _gc_lock_counter = 0;
|
||||||
|
struct ScopeLock{
|
||||||
|
ManagedHeap* heap;
|
||||||
|
ScopeLock(ManagedHeap* heap): heap(heap){
|
||||||
|
heap->_gc_lock_counter++;
|
||||||
|
}
|
||||||
|
~ScopeLock(){
|
||||||
|
heap->_gc_lock_counter--;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ScopeLock gc_scope_lock(){
|
||||||
|
return ScopeLock(this);
|
||||||
|
}
|
||||||
|
/********************/
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
PyObject* gcnew(Type type, T&& val){
|
PyObject* gcnew(Type type, T&& val){
|
||||||
PyObject* obj = new Py_<std::decay_t<T>>(type, std::forward<T>(val));
|
PyObject* obj = new Py_<std::decay_t<T>>(type, std::forward<T>(val));
|
||||||
@ -98,6 +115,7 @@ struct ManagedHeap{
|
|||||||
void _delete_hook(VM* vm, PyObject* obj);
|
void _delete_hook(VM* vm, PyObject* obj);
|
||||||
|
|
||||||
void _auto_collect(VM* vm){
|
void _auto_collect(VM* vm){
|
||||||
|
if(_gc_lock_counter > 0) return;
|
||||||
if(gc_counter < gc_threshold) return;
|
if(gc_counter < gc_threshold) return;
|
||||||
gc_counter = 0;
|
gc_counter = 0;
|
||||||
collect(vm);
|
collect(vm);
|
||||||
@ -106,6 +124,7 @@ struct ManagedHeap{
|
|||||||
}
|
}
|
||||||
|
|
||||||
int collect(VM* vm){
|
int collect(VM* vm){
|
||||||
|
if(_gc_lock_counter > 0) UNREACHABLE();
|
||||||
mark(vm);
|
mark(vm);
|
||||||
int freed = sweep(vm);
|
int freed = sweep(vm);
|
||||||
return freed;
|
return freed;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user