mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
up
This commit is contained in:
parent
818ee2981e
commit
7ce783360f
13
src/ceval.h
13
src/ceval.h
@ -15,11 +15,14 @@ __NEXT_STEP:;
|
||||
* For example, frame->popx() returns a strong reference which may be dangerous
|
||||
* `Args` containing strong references is safe if it is passed to `call` or `fast_call`
|
||||
*/
|
||||
//heap._auto_collect(this);
|
||||
#if !DEBUG_NO_GC
|
||||
heap._auto_collect(this);
|
||||
#endif
|
||||
|
||||
const Bytecode& byte = frame->next_bytecode();
|
||||
|
||||
// std::cout << frame->stack_info() << " " << OP_NAMES[byte.op] << std::endl;
|
||||
#if DEBUG_CEVAL_STEP
|
||||
std::cout << frame->stack_info() << " " << OP_NAMES[byte.op] << std::endl;
|
||||
#endif
|
||||
|
||||
switch (byte.op)
|
||||
{
|
||||
@ -298,8 +301,10 @@ __NEXT_STEP:;
|
||||
PyObject* new_mod = new_module(name);
|
||||
_exec(code, new_mod, builtins);
|
||||
new_mod->attr()._try_perfect_rehash();
|
||||
}
|
||||
frame->push(new_mod);
|
||||
}else{
|
||||
frame->push(ext_mod);
|
||||
}
|
||||
} DISPATCH();
|
||||
case OP_IMPORT_STAR: {
|
||||
PyObject* obj = frame->popx();
|
||||
|
10
src/common.h
10
src/common.h
@ -32,15 +32,17 @@
|
||||
|
||||
// debug macros
|
||||
#define DEBUG_NO_BUILTIN_MODULES 0
|
||||
#define DEBUG_EXTRA_CHECK 1
|
||||
#define DEBUG_DIS_REPL 0
|
||||
#define DEBUG_DIS_REPL_MIN 1
|
||||
#define DEBUG_EXTRA_CHECK 0
|
||||
#define DEBUG_DIS_EXEC_REPL 0
|
||||
#define DEBUG_DIS_EXEC_REPL_MIN 1
|
||||
#define DEBUG_CEVAL_STEP 0
|
||||
#define DEBUG_FULL_EXCEPTION 0
|
||||
#define DEBUG_NO_GC 1
|
||||
|
||||
#if (defined(__ANDROID__) && __ANDROID_API__ <= 22) || defined(__EMSCRIPTEN__)
|
||||
#define PK_ENABLE_FILEIO 0
|
||||
#else
|
||||
#define PK_ENABLE_FILEIO (1-DEBUG_NO_BUILTIN_MODULES)
|
||||
#define PK_ENABLE_FILEIO 0 // TODO: refactor this
|
||||
#endif
|
||||
|
||||
#if defined(__EMSCRIPTEN__) || defined(__arm__) || defined(__i386__)
|
||||
|
@ -757,15 +757,15 @@ __SUBSCR_END:
|
||||
} break;
|
||||
case TK("with"): {
|
||||
// TODO: reimpl this
|
||||
UNREACHABLE();
|
||||
// EXPR(false);
|
||||
// consume(TK("as"));
|
||||
// consume(TK("@id"));
|
||||
// int index = ctx()->add_name(prev().str(), name_scope());
|
||||
EXPR(false);
|
||||
ctx()->emit(OP_POP_TOP, BC_NOARG, prev().line);
|
||||
consume(TK("as"));
|
||||
consume(TK("@id"));
|
||||
// int index = ctx()->add_name(prev().str());
|
||||
// emit(OP_STORE_NAME, index);
|
||||
// emit(OP_LOAD_NAME_REF, index);
|
||||
// emit(OP_WITH_ENTER);
|
||||
// compile_block_body();
|
||||
compile_block_body();
|
||||
// emit(OP_LOAD_NAME_REF, index);
|
||||
// emit(OP_WITH_EXIT);
|
||||
} break;
|
||||
@ -958,12 +958,11 @@ public:
|
||||
pop_context();
|
||||
return code;
|
||||
}else if(mode()==JSON_MODE){
|
||||
PyObject* value = read_literal();
|
||||
if(value != nullptr) ctx()->emit(OP_LOAD_CONST, ctx()->add_const(value), prev().line);
|
||||
else if(match(TK("{"))) exprMap();
|
||||
else if(match(TK("["))) exprList();
|
||||
else SyntaxError("expect a JSON object or array");
|
||||
EXPR();
|
||||
Expr_ e = ctx()->s_expr.popx();
|
||||
if(!e->is_json_object()) SyntaxError("expect a JSON object, literal or array");
|
||||
consume(TK("@eof"));
|
||||
e->emit(ctx());
|
||||
ctx()->emit(OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
|
||||
pop_context();
|
||||
return code;
|
||||
|
12
src/expr.h
12
src/expr.h
@ -20,6 +20,7 @@ struct Expr{
|
||||
virtual std::vector<const Expr*> children() const { return {}; }
|
||||
virtual bool is_starred() const { return false; }
|
||||
virtual bool is_literal() const { return false; }
|
||||
virtual bool is_json_object() const { return false; }
|
||||
|
||||
// for OP_DELETE_XXX
|
||||
virtual bool emit_del(CodeEmitContext* ctx) { return false; }
|
||||
@ -238,6 +239,8 @@ struct Literal0Expr: Expr{
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
bool is_json_object() const override { return true; }
|
||||
};
|
||||
|
||||
// @num, @str which needs to invoke OP_LOAD_CONST
|
||||
@ -283,6 +286,7 @@ struct LiteralExpr: Expr{
|
||||
}
|
||||
|
||||
bool is_literal() const override { return true; }
|
||||
bool is_json_object() const override { return true; }
|
||||
};
|
||||
|
||||
// PASS
|
||||
@ -313,6 +317,10 @@ struct NegatedExpr: Expr{
|
||||
child->emit(ctx);
|
||||
ctx->emit(OP_UNARY_NEGATIVE, BC_NOARG, line);
|
||||
}
|
||||
|
||||
bool is_json_object() const override {
|
||||
return child->is_literal();
|
||||
}
|
||||
};
|
||||
|
||||
// PASS
|
||||
@ -384,12 +392,16 @@ struct ListExpr: SequenceExpr{
|
||||
using SequenceExpr::SequenceExpr;
|
||||
Str str() const override { return "list()"; }
|
||||
Opcode opcode() const override { return OP_BUILD_LIST; }
|
||||
|
||||
bool is_json_object() const override { return true; }
|
||||
};
|
||||
|
||||
struct DictExpr: SequenceExpr{
|
||||
using SequenceExpr::SequenceExpr;
|
||||
Str str() const override { return "dict()"; }
|
||||
Opcode opcode() const override { return OP_BUILD_DICT; }
|
||||
|
||||
bool is_json_object() const override { return true; }
|
||||
};
|
||||
|
||||
struct SetExpr: SequenceExpr{
|
||||
|
10
src/frame.h
10
src/frame.h
@ -46,7 +46,7 @@ struct Frame {
|
||||
|
||||
Str stack_info(){
|
||||
StrStream ss;
|
||||
ss << "[";
|
||||
ss << id << " [";
|
||||
for(int i=0; i<_data.size(); i++){
|
||||
ss << (i64)_data[i];
|
||||
if(i != _data.size()-1) ss << ", ";
|
||||
@ -93,8 +93,12 @@ struct Frame {
|
||||
return _data[_data.size()-n];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void push(T&& obj){ _data.push_back(std::forward<T>(obj)); }
|
||||
void push(PyObject* obj){
|
||||
#if DEBUG_EXTRA_CHECK
|
||||
if(obj == nullptr) throw std::runtime_error("obj == nullptr");
|
||||
#endif
|
||||
_data.push_back(obj);
|
||||
}
|
||||
|
||||
void jump_abs(int i){ _next_ip = i; }
|
||||
void jump_rel(int i){ _next_ip += i; }
|
||||
|
@ -172,11 +172,10 @@ inline void init_builtins(VM* _vm) {
|
||||
|
||||
_vm->bind_method<0>("object", "__repr__", [](VM* vm, Args& args) {
|
||||
PyObject* self = args[0];
|
||||
std::uintptr_t addr = is_tagged(self) ? 0 : (uintptr_t)self;
|
||||
if(is_tagged(self)) self = nullptr;
|
||||
StrStream ss;
|
||||
ss << std::hex << addr;
|
||||
Str s = "<" + OBJ_NAME(vm->_t(self)) + " object at 0x" + ss.str() + ">";
|
||||
return VAR(s);
|
||||
ss << "<" << OBJ_NAME(vm->_t(self)) << " object at " << std::hex << self << ">";
|
||||
return VAR(ss.str());
|
||||
});
|
||||
|
||||
_vm->bind_method<1>("object", "__eq__", CPP_LAMBDA(VAR(args[0] == args[1])));
|
||||
|
5
src/vm.h
5
src/vm.h
@ -166,7 +166,7 @@ public:
|
||||
if(_module == nullptr) _module = _main;
|
||||
try {
|
||||
CodeObject_ code = compile(source, filename, mode);
|
||||
#if DEBUG_DIS_REPL
|
||||
#if DEBUG_DIS_EXEC_REPL
|
||||
if(_module == _main) std::cout << disassemble(code) << '\n';
|
||||
#endif
|
||||
return _exec(code, _module, builtins);
|
||||
@ -596,6 +596,7 @@ inline Str VM::disassemble(CodeObject_ co){
|
||||
break;
|
||||
case OP_LOAD_NAME: case OP_STORE_LOCAL: case OP_STORE_GLOBAL:
|
||||
case OP_LOAD_ATTR: case OP_STORE_ATTR: case OP_DELETE_ATTR:
|
||||
case OP_IMPORT_NAME: case OP_BEGIN_CLASS:
|
||||
case OP_DELETE_LOCAL: case OP_DELETE_GLOBAL:
|
||||
argStr += " (" + co->names[byte.arg].str().escape(true) + ")";
|
||||
break;
|
||||
@ -614,7 +615,7 @@ inline Str VM::disassemble(CodeObject_ co){
|
||||
if(i != co->codes.size() - 1) ss << '\n';
|
||||
}
|
||||
|
||||
#if !DEBUG_DIS_REPL_MIN
|
||||
#if !DEBUG_DIS_EXEC_REPL_MIN
|
||||
StrStream consts;
|
||||
consts << "co_consts: ";
|
||||
consts << CAST(Str, asRepr(VAR(co->consts)));
|
||||
|
@ -11,21 +11,21 @@ r.shuffle(a)
|
||||
r.choice(a)
|
||||
r.choice(b)
|
||||
|
||||
from sys import version as v
|
||||
# from sys import version as v
|
||||
|
||||
assert type(v) is str
|
||||
# assert type(v) is str
|
||||
|
||||
class Context:
|
||||
def __init__(self):
|
||||
self.x = 0
|
||||
# class Context:
|
||||
# def __init__(self):
|
||||
# self.x = 0
|
||||
|
||||
def __enter__(self):
|
||||
self.x = 1
|
||||
# def __enter__(self):
|
||||
# self.x = 1
|
||||
|
||||
def __exit__(self):
|
||||
self.x = 2
|
||||
# def __exit__(self):
|
||||
# self.x = 2
|
||||
|
||||
with Context() as c:
|
||||
assert c.x == 1
|
||||
# with Context() as c:
|
||||
# assert c.x == 1
|
||||
|
||||
assert c.x == 2
|
||||
# assert c.x == 2
|
Loading…
x
Reference in New Issue
Block a user