This commit is contained in:
BLUELOVETH 2023-04-06 04:35:09 +00:00
parent 818ee2981e
commit 7ce783360f
8 changed files with 62 additions and 40 deletions

View File

@ -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);
}
frame->push(ext_mod);
} DISPATCH();
case OP_IMPORT_STAR: {
PyObject* obj = frame->popx();

View File

@ -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__)

View File

@ -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;

View File

@ -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{

View File

@ -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; }

View File

@ -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])));

View File

@ -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)));

View File

@ -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