mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-22 04:20:17 +00:00
up
This commit is contained in:
parent
8364adef70
commit
d1f5d31849
220
src/ceval.h
220
src/ceval.h
@ -13,19 +13,28 @@ inline PyObject* VM::run_frame(Frame* frame){
|
||||
switch (byte.op)
|
||||
{
|
||||
case OP_NO_OP: continue;
|
||||
case OP_SETUP_DECORATOR: continue;
|
||||
/*****************************************/
|
||||
case OP_POP_TOP: frame->pop(); continue;
|
||||
case OP_DUP_TOP: frame->push(frame->top()); continue;
|
||||
case OP_ROT_TWO: std::swap(frame->top(), frame->top_1()); continue;
|
||||
case OP_PRINT_EXPR: {
|
||||
PyObject* obj = frame->top(); // use top() here to avoid accidental gc
|
||||
if(obj != None) *_stdout << CAST(Str, asRepr(obj)) << '\n';
|
||||
frame->pop();
|
||||
} continue;
|
||||
/*****************************************/
|
||||
case OP_LOAD_CONST: frame->push(frame->co->consts[byte.arg]); continue;
|
||||
case OP_LOAD_NONE: frame->push(None); continue;
|
||||
case OP_LOAD_TRUE: frame->push(True); continue;
|
||||
case OP_LOAD_FALSE: frame->push(False); continue;
|
||||
case OP_LOAD_ELLIPSIS: frame->push(Ellipsis); continue;
|
||||
case OP_LOAD_BUILTINS_EVAL: frame->push(builtins->attr(m_eval)); continue;
|
||||
case OP_LOAD_FUNCTION: {
|
||||
PyObject* obj = frame->co->consts[byte.arg];
|
||||
Function f = CAST(Function, obj); // copy
|
||||
f._module = frame->_module;
|
||||
frame->push(VAR(f));
|
||||
Function f = CAST(Function, obj); // copy it!
|
||||
f._module = frame->_module; // setup module
|
||||
frame->push(VAR(std::move(f)));
|
||||
} continue;
|
||||
case OP_SETUP_CLOSURE: {
|
||||
Function& f = CAST(Function&, frame->top()); // reference
|
||||
f._closure = frame->_locals;
|
||||
} continue;
|
||||
case OP_ROT_TWO: ::std::swap(frame->top(), frame->top_1()); continue;
|
||||
/*****************************************/
|
||||
case OP_LOAD_NAME: {
|
||||
StrName name = frame->co->names[byte.arg];
|
||||
@ -116,9 +125,9 @@ inline PyObject* VM::run_frame(Frame* frame){
|
||||
PyObject* stop = frame->popx();
|
||||
PyObject* start = frame->popx();
|
||||
Slice s;
|
||||
if(start != None) { s.start = CAST(int, start);}
|
||||
if(stop != None) { s.stop = CAST(int, stop);}
|
||||
if(step != None) { s.step = CAST(int, step);}
|
||||
if(start != None) s.start = CAST(int, start);
|
||||
if(stop != None) s.stop = CAST(int, stop);
|
||||
if(step != None) s.step = CAST(int, step);
|
||||
frame->push(VAR(s));
|
||||
} continue;
|
||||
case OP_BUILD_TUPLE: {
|
||||
@ -132,7 +141,99 @@ inline PyObject* VM::run_frame(Frame* frame){
|
||||
frame->push(VAR(ss.str()));
|
||||
} continue;
|
||||
/*****************************************/
|
||||
case OP_LOAD_EVAL_FN: frame->push(builtins->attr(m_eval)); continue;
|
||||
case OP_BINARY_OP: {
|
||||
Args args(2);
|
||||
args[1] = frame->popx(); // lhs
|
||||
args[0] = frame->top(); // rhs
|
||||
frame->top() = fast_call(BINARY_SPECIAL_METHODS[byte.arg], std::move(args));
|
||||
} continue;
|
||||
case OP_COMPARE_OP: {
|
||||
Args args(2);
|
||||
args[1] = frame->popx(); // lhs
|
||||
args[0] = frame->top(); // rhs
|
||||
frame->top() = fast_call(COMPARE_SPECIAL_METHODS[byte.arg], std::move(args));
|
||||
} continue;
|
||||
case OP_BITWISE_OP: {
|
||||
Args args(2);
|
||||
args[1] = frame->popx(); // lhs
|
||||
args[0] = frame->top(); // rhs
|
||||
frame->top() = fast_call(BITWISE_SPECIAL_METHODS[byte.arg], std::move(args));
|
||||
} continue;
|
||||
case OP_IS_OP: {
|
||||
PyObject* rhs = frame->popx();
|
||||
PyObject* lhs = frame->top();
|
||||
bool ret_c = lhs == rhs;
|
||||
if(byte.arg == 1) ret_c = !ret_c;
|
||||
frame->top() = VAR(ret_c);
|
||||
} continue;
|
||||
case OP_CONTAINS_OP: {
|
||||
Args args(2);
|
||||
args[0] = frame->popx();
|
||||
args[1] = frame->top();
|
||||
PyObject* ret = fast_call(__contains__, std::move(args));
|
||||
bool ret_c = CAST(bool, ret);
|
||||
if(byte.arg == 1) ret_c = !ret_c;
|
||||
frame->top() = VAR(ret_c);
|
||||
} continue;
|
||||
/*****************************************/
|
||||
case OP_JUMP_ABSOLUTE: frame->jump_abs(byte.arg); continue;
|
||||
case OP_SAFE_JUMP_ABSOLUTE: frame->jump_abs_safe(byte.arg); continue;
|
||||
case OP_POP_JUMP_IF_FALSE:
|
||||
if(!asBool(frame->popx())) frame->jump_abs(byte.arg);
|
||||
continue;
|
||||
case OP_JUMP_IF_TRUE_OR_POP:
|
||||
if(asBool(frame->top()) == true) frame->jump_abs(byte.arg);
|
||||
else frame->pop();
|
||||
continue;
|
||||
case OP_JUMP_IF_FALSE_OR_POP:
|
||||
if(asBool(frame->top()) == false) frame->jump_abs(byte.arg);
|
||||
else frame->pop();
|
||||
continue;
|
||||
case OP_LOOP_CONTINUE: {
|
||||
int target = frame->co->blocks[byte.block].start;
|
||||
frame->jump_abs(target);
|
||||
} continue;
|
||||
case OP_LOOP_BREAK: {
|
||||
int target = frame->co->blocks[byte.block].end;
|
||||
frame->jump_abs_safe(target);
|
||||
} continue;
|
||||
case OP_GOTO: {
|
||||
StrName label = frame->co->names[byte.arg];
|
||||
auto it = frame->co->labels.find(label);
|
||||
if(it == frame->co->labels.end()) _error("KeyError", "label " + label.str().escape(true) + " not found");
|
||||
frame->jump_abs_safe(it->second);
|
||||
} continue;
|
||||
/*****************************************/
|
||||
// TODO: examine this later
|
||||
case OP_CALL: case OP_CALL_UNPACK: {
|
||||
Args args = frame->popx_n_reversed(byte.arg);
|
||||
if(byte.op == OP_CALL_UNPACK) unpack_args(args);
|
||||
PyObject* callable = frame->popx();
|
||||
PyObject* ret = call(callable, std::move(args), no_arg(), true);
|
||||
if(ret == _py_op_call) return ret;
|
||||
frame->push(std::move(ret));
|
||||
} continue;
|
||||
case OP_CALL_KWARGS: case OP_CALL_KWARGS_UNPACK: {
|
||||
int ARGC = byte.arg & 0xFFFF;
|
||||
int KWARGC = (byte.arg >> 16) & 0xFFFF;
|
||||
Args kwargs = frame->popx_n_reversed(KWARGC*2);
|
||||
Args args = frame->popx_n_reversed(ARGC);
|
||||
if(byte.op == OP_CALL_KWARGS_UNPACK) unpack_args(args);
|
||||
PyObject* callable = frame->popx();
|
||||
PyObject* ret = call(callable, std::move(args), kwargs, true);
|
||||
if(ret == _py_op_call) return ret;
|
||||
frame->push(std::move(ret));
|
||||
} continue;
|
||||
case OP_RETURN_VALUE: return frame->popx();
|
||||
/*****************************************/
|
||||
|
||||
/*****************************************/
|
||||
case OP_SETUP_DECORATOR: continue;
|
||||
|
||||
case OP_SETUP_CLOSURE: {
|
||||
Function& f = CAST(Function&, frame->top()); // reference
|
||||
f._closure = frame->_locals;
|
||||
} continue;
|
||||
case OP_BEGIN_CLASS: {
|
||||
StrName name = frame->co->names[byte.arg];
|
||||
PyObject* clsBase = frame->popx();
|
||||
@ -151,43 +252,7 @@ inline PyObject* VM::run_frame(Frame* frame){
|
||||
PyObject* cls = frame->top();
|
||||
cls->attr().set(name, obj);
|
||||
} continue;
|
||||
case OP_RETURN_VALUE: return frame->popx();
|
||||
case OP_PRINT_EXPR: {
|
||||
PyObject* expr = frame->top(); // use top() here to avoid accidental gc
|
||||
if(expr != None) *_stdout << CAST(Str, asRepr(expr)) << '\n';
|
||||
frame->pop();
|
||||
} continue;
|
||||
case OP_POP_TOP: frame->_pop(); continue;
|
||||
case OP_BINARY_OP: {
|
||||
Args args(2);
|
||||
args[1] = frame->pop_value(this);
|
||||
args[0] = frame->top_value(this);
|
||||
frame->top() = fast_call(BINARY_SPECIAL_METHODS[byte.arg], std::move(args));
|
||||
} continue;
|
||||
case OP_BITWISE_OP: {
|
||||
Args args(2);
|
||||
args[1] = frame->pop_value(this);
|
||||
args[0] = frame->top_value(this);
|
||||
frame->top() = fast_call(BITWISE_SPECIAL_METHODS[byte.arg], std::move(args));
|
||||
} continue;
|
||||
case OP_COMPARE_OP: {
|
||||
Args args(2);
|
||||
args[1] = frame->pop_value(this);
|
||||
args[0] = frame->top_value(this);
|
||||
frame->top() = fast_call(CMP_SPECIAL_METHODS[byte.arg], std::move(args));
|
||||
} continue;
|
||||
case OP_IS_OP: {
|
||||
PyObject* rhs = frame->pop_value(this);
|
||||
bool ret_c = rhs == frame->top_value(this);
|
||||
if(byte.arg == 1) ret_c = !ret_c;
|
||||
frame->top() = VAR(ret_c);
|
||||
} continue;
|
||||
case OP_CONTAINS_OP: {
|
||||
PyObject* rhs = frame->pop_value(this);
|
||||
bool ret_c = CAST(bool, call(rhs, __contains__, Args{frame->pop_value(this)}));
|
||||
if(byte.arg == 1) ret_c = !ret_c;
|
||||
frame->push(VAR(ret_c));
|
||||
} continue;
|
||||
|
||||
case OP_UNARY_NEGATIVE:
|
||||
frame->top() = num_negated(frame->top_value(this));
|
||||
continue;
|
||||
@ -196,13 +261,7 @@ inline PyObject* VM::run_frame(Frame* frame){
|
||||
PyObject* obj_bool = asBool(obj);
|
||||
frame->push(VAR(!_CAST(bool, obj_bool)));
|
||||
} continue;
|
||||
case OP_POP_JUMP_IF_FALSE:
|
||||
if(!_CAST(bool, asBool(frame->pop_value(this)))) frame->jump_abs(byte.arg);
|
||||
continue;
|
||||
case OP_LOAD_NONE: frame->push(None); continue;
|
||||
case OP_LOAD_TRUE: frame->push(True); continue;
|
||||
case OP_LOAD_FALSE: frame->push(False); continue;
|
||||
case OP_LOAD_ELLIPSIS: frame->push(Ellipsis); continue;
|
||||
|
||||
case OP_ASSERT: {
|
||||
PyObject* _msg = frame->pop_value(this);
|
||||
Str msg = CAST(Str, asStr(_msg));
|
||||
@ -236,7 +295,6 @@ inline PyObject* VM::run_frame(Frame* frame){
|
||||
PyObject* obj = frame->pop_value(this);
|
||||
call(frame->top_1(), "add", Args{obj});
|
||||
} continue;
|
||||
case OP_DUP_TOP: frame->push(frame->top()); continue;
|
||||
case OP_UNARY_STAR: {
|
||||
if(byte.arg > 0){ // rvalue
|
||||
frame->top() = VAR(StarWrapper(frame->top_value(this), true));
|
||||
@ -245,33 +303,6 @@ inline PyObject* VM::run_frame(Frame* frame){
|
||||
frame->top() = VAR(StarWrapper(frame->top(), false));
|
||||
}
|
||||
} continue;
|
||||
case OP_CALL_KWARGS_UNPACK: case OP_CALL_KWARGS: {
|
||||
int ARGC = byte.arg & 0xFFFF;
|
||||
int KWARGC = (byte.arg >> 16) & 0xFFFF;
|
||||
Args kwargs = frame->pop_n_values_reversed(this, KWARGC*2);
|
||||
Args args = frame->pop_n_values_reversed(this, ARGC);
|
||||
if(byte.op == OP_CALL_KWARGS_UNPACK) unpack_args(args);
|
||||
PyObject* callable = frame->pop_value(this);
|
||||
PyObject* ret = call(callable, std::move(args), kwargs, true);
|
||||
if(ret == _py_op_call) return ret;
|
||||
frame->push(std::move(ret));
|
||||
} continue;
|
||||
case OP_CALL_UNPACK: case OP_CALL: {
|
||||
Args args = frame->pop_n_values_reversed(this, byte.arg);
|
||||
if(byte.op == OP_CALL_UNPACK) unpack_args(args);
|
||||
PyObject* callable = frame->pop_value(this);
|
||||
PyObject* ret = call(callable, std::move(args), no_arg(), true);
|
||||
if(ret == _py_op_call) return ret;
|
||||
frame->push(std::move(ret));
|
||||
} continue;
|
||||
case OP_JUMP_ABSOLUTE: frame->jump_abs(byte.arg); continue;
|
||||
case OP_SAFE_JUMP_ABSOLUTE: frame->jump_abs_safe(byte.arg); continue;
|
||||
case OP_GOTO: {
|
||||
StrName label = frame->co->names[byte.arg].first;
|
||||
auto it = frame->co->labels.find(label);
|
||||
if(it == frame->co->labels.end()) _error("KeyError", "label " + label.str().escape(true) + " not found");
|
||||
frame->jump_abs_safe(it->second);
|
||||
} continue;
|
||||
case OP_GET_ITER: {
|
||||
PyObject* obj = frame->pop_value(this);
|
||||
PyObject* iter = asIter(obj);
|
||||
@ -289,24 +320,7 @@ inline PyObject* VM::run_frame(Frame* frame){
|
||||
frame->jump_abs_safe(blockEnd);
|
||||
}
|
||||
} continue;
|
||||
case OP_LOOP_CONTINUE: {
|
||||
int blockStart = frame->co->blocks[byte.block].start;
|
||||
frame->jump_abs(blockStart);
|
||||
} continue;
|
||||
case OP_LOOP_BREAK: {
|
||||
int blockEnd = frame->co->blocks[byte.block].end;
|
||||
frame->jump_abs_safe(blockEnd);
|
||||
} continue;
|
||||
case OP_JUMP_IF_FALSE_OR_POP: {
|
||||
PyObject* expr = frame->top_value(this);
|
||||
if(asBool(expr)==False) frame->jump_abs(byte.arg);
|
||||
else frame->pop_value(this);
|
||||
} continue;
|
||||
case OP_JUMP_IF_TRUE_OR_POP: {
|
||||
PyObject* expr = frame->top_value(this);
|
||||
if(asBool(expr)==True) frame->jump_abs(byte.arg);
|
||||
else frame->pop_value(this);
|
||||
} continue;
|
||||
|
||||
|
||||
case OP_IMPORT_NAME: {
|
||||
StrName name = frame->co->names[byte.arg].first;
|
||||
|
11
src/expr.h
11
src/expr.h
@ -425,7 +425,7 @@ struct FStringExpr: Expr{
|
||||
ctx->emit(OP_LOAD_CONST, ctx->add_const(VAR(literal)), line);
|
||||
size++;
|
||||
}
|
||||
ctx->emit(OP_LOAD_EVAL_FN, BC_NOARG, line);
|
||||
ctx->emit(OP_LOAD_BUILTINS_EVAL, BC_NOARG, line);
|
||||
ctx->emit(OP_LOAD_CONST, ctx->add_const(VAR(m[1].str())), line);
|
||||
ctx->emit(OP_CALL, 1, line);
|
||||
size++;
|
||||
@ -514,7 +514,16 @@ struct CallExpr: Expr{
|
||||
}
|
||||
|
||||
void emit(CodeEmitContext* ctx) override {
|
||||
VM* vm = ctx->vm;
|
||||
callable->emit(ctx);
|
||||
// emit args
|
||||
for(auto& item: args) item->emit(ctx);
|
||||
// emit kwargs
|
||||
for(auto& item: kwargs){
|
||||
// TODO: optimize this
|
||||
ctx->emit(OP_LOAD_CONST, ctx->add_const(VAR(item.first)), line);
|
||||
item.second->emit(ctx);
|
||||
}
|
||||
int KWARGC = (int)kwargs.size();
|
||||
int ARGC = (int)args.size();
|
||||
if(KWARGC > 0){
|
||||
|
@ -1,21 +1,5 @@
|
||||
#ifdef OPCODE
|
||||
|
||||
OPCODE(NO_OP)
|
||||
OPCODE(POP_TOP)
|
||||
OPCODE(DUP_TOP)
|
||||
OPCODE(CALL)
|
||||
OPCODE(CALL_UNPACK)
|
||||
OPCODE(CALL_KWARGS)
|
||||
OPCODE(CALL_KWARGS_UNPACK)
|
||||
OPCODE(RETURN_VALUE)
|
||||
OPCODE(ROT_TWO)
|
||||
|
||||
OPCODE(BINARY_OP)
|
||||
OPCODE(COMPARE_OP)
|
||||
OPCODE(BITWISE_OP)
|
||||
OPCODE(IS_OP)
|
||||
OPCODE(CONTAINS_OP)
|
||||
|
||||
OPCODE(UNARY_NEGATIVE)
|
||||
OPCODE(UNARY_NOT)
|
||||
OPCODE(UNARY_STAR)
|
||||
@ -23,32 +7,14 @@ OPCODE(UNARY_STAR)
|
||||
OPCODE(LIST_APPEND)
|
||||
OPCODE(MAP_ADD)
|
||||
OPCODE(SET_ADD)
|
||||
|
||||
OPCODE(IMPORT_NAME)
|
||||
OPCODE(PRINT_EXPR)
|
||||
|
||||
OPCODE(GET_ITER)
|
||||
OPCODE(FOR_ITER)
|
||||
|
||||
OPCODE(WITH_ENTER)
|
||||
OPCODE(WITH_EXIT)
|
||||
OPCODE(LOOP_BREAK)
|
||||
OPCODE(LOOP_CONTINUE)
|
||||
|
||||
OPCODE(POP_JUMP_IF_FALSE)
|
||||
OPCODE(JUMP_ABSOLUTE)
|
||||
OPCODE(SAFE_JUMP_ABSOLUTE)
|
||||
OPCODE(JUMP_IF_TRUE_OR_POP)
|
||||
OPCODE(JUMP_IF_FALSE_OR_POP)
|
||||
|
||||
OPCODE(GOTO)
|
||||
|
||||
OPCODE(LOAD_CONST)
|
||||
OPCODE(LOAD_NONE)
|
||||
OPCODE(LOAD_TRUE)
|
||||
OPCODE(LOAD_FALSE)
|
||||
OPCODE(LOAD_EVAL_FN)
|
||||
OPCODE(LOAD_FUNCTION)
|
||||
OPCODE(LOAD_ELLIPSIS)
|
||||
|
||||
OPCODE(ASSERT)
|
||||
OPCODE(EXCEPTION_MATCH)
|
||||
@ -62,9 +28,6 @@ OPCODE(TRY_BLOCK_EXIT)
|
||||
|
||||
OPCODE(YIELD_VALUE)
|
||||
|
||||
OPCODE(FAST_INDEX) // a[x]
|
||||
OPCODE(FAST_INDEX_REF) // a[x]
|
||||
|
||||
OPCODE(SETUP_CLOSURE)
|
||||
OPCODE(SETUP_DECORATOR)
|
||||
OPCODE(STORE_ALL_NAMES)
|
||||
@ -73,6 +36,22 @@ OPCODE(BEGIN_CLASS)
|
||||
OPCODE(END_CLASS)
|
||||
OPCODE(STORE_CLASS_ATTR)
|
||||
|
||||
|
||||
/**************************/
|
||||
OPCODE(NO_OP)
|
||||
/**************************/
|
||||
OPCODE(POP_TOP)
|
||||
OPCODE(DUP_TOP)
|
||||
OPCODE(ROT_TWO)
|
||||
OPCODE(PRINT_EXPR)
|
||||
/**************************/
|
||||
OPCODE(LOAD_CONST)
|
||||
OPCODE(LOAD_NONE)
|
||||
OPCODE(LOAD_TRUE)
|
||||
OPCODE(LOAD_FALSE)
|
||||
OPCODE(LOAD_ELLIPSIS)
|
||||
OPCODE(LOAD_BUILTINS_EVAL)
|
||||
OPCODE(LOAD_FUNCTION)
|
||||
/**************************/
|
||||
OPCODE(LOAD_NAME)
|
||||
OPCODE(LOAD_ATTR)
|
||||
@ -95,5 +74,26 @@ OPCODE(BUILD_SLICE)
|
||||
OPCODE(BUILD_TUPLE)
|
||||
OPCODE(BUILD_STRING)
|
||||
/**************************/
|
||||
OPCODE(BINARY_OP)
|
||||
OPCODE(COMPARE_OP)
|
||||
OPCODE(BITWISE_OP)
|
||||
OPCODE(IS_OP)
|
||||
OPCODE(CONTAINS_OP)
|
||||
/**************************/
|
||||
OPCODE(JUMP_ABSOLUTE)
|
||||
OPCODE(SAFE_JUMP_ABSOLUTE)
|
||||
OPCODE(POP_JUMP_IF_FALSE)
|
||||
OPCODE(JUMP_IF_TRUE_OR_POP)
|
||||
OPCODE(JUMP_IF_FALSE_OR_POP)
|
||||
OPCODE(LOOP_CONTINUE)
|
||||
OPCODE(LOOP_BREAK)
|
||||
OPCODE(GOTO)
|
||||
/**************************/
|
||||
OPCODE(CALL)
|
||||
OPCODE(CALL_UNPACK)
|
||||
OPCODE(CALL_KWARGS)
|
||||
OPCODE(CALL_KWARGS_UNPACK)
|
||||
OPCODE(RETURN_VALUE)
|
||||
/**************************/
|
||||
|
||||
#endif
|
@ -214,7 +214,7 @@ const StrName m_set = StrName::get("set");
|
||||
const StrName __enter__ = StrName::get("__enter__");
|
||||
const StrName __exit__ = StrName::get("__exit__");
|
||||
|
||||
const StrName CMP_SPECIAL_METHODS[] = {
|
||||
const StrName COMPARE_SPECIAL_METHODS[] = {
|
||||
StrName::get("__lt__"), StrName::get("__le__"), StrName::get("__eq__"),
|
||||
StrName::get("__ne__"), StrName::get("__gt__"), StrName::get("__ge__")
|
||||
};
|
||||
|
52
src/vm.h
52
src/vm.h
@ -320,7 +320,7 @@ public:
|
||||
CodeObject_ compile(Str source, Str filename, CompileMode mode);
|
||||
PyObject* num_negated(PyObject* obj);
|
||||
f64 num_to_float(PyObject* obj);
|
||||
PyObject* asBool(PyObject* obj);
|
||||
bool asBool(PyObject* obj);
|
||||
i64 hash(PyObject* obj);
|
||||
PyObject* asRepr(PyObject* obj);
|
||||
PyObject* new_module(StrName name);
|
||||
@ -357,30 +357,13 @@ inline void CodeObject::optimize(VM* vm){
|
||||
perfect_locals_capacity = find_next_capacity(base_n);
|
||||
perfect_hash_seed = find_perfect_hash_seed(perfect_locals_capacity, keys);
|
||||
|
||||
// for(int i=1; i<codes.size(); i++){
|
||||
// if(codes[i].op == OP_UNARY_NEGATIVE && codes[i-1].op == OP_LOAD_CONST){
|
||||
// codes[i].op = OP_NO_OP;
|
||||
// int pos = codes[i-1].arg;
|
||||
// consts[pos] = vm->num_negated(consts[pos]);
|
||||
// }
|
||||
|
||||
// if(i>=2 && codes[i].op == OP_BUILD_INDEX){
|
||||
// const Bytecode& a = codes[i-1];
|
||||
// const Bytecode& x = codes[i-2];
|
||||
// if(codes[i].arg == 1){
|
||||
// if(a.op == OP_LOAD_NAME && x.op == OP_LOAD_NAME){
|
||||
// codes[i].op = OP_FAST_INDEX;
|
||||
// }else continue;
|
||||
// }else{
|
||||
// if(a.op == OP_LOAD_NAME_REF && x.op == OP_LOAD_NAME_REF){
|
||||
// codes[i].op = OP_FAST_INDEX_REF;
|
||||
// }else continue;
|
||||
// }
|
||||
// codes[i].arg = (a.arg << 16) | x.arg;
|
||||
// codes[i-1].op = OP_NO_OP;
|
||||
// codes[i-2].op = OP_NO_OP;
|
||||
// }
|
||||
// }
|
||||
for(int i=1; i<codes.size(); i++){
|
||||
if(codes[i].op == OP_UNARY_NEGATIVE && codes[i-1].op == OP_LOAD_CONST){
|
||||
codes[i].op = OP_NO_OP;
|
||||
int pos = codes[i-1].arg;
|
||||
consts[pos] = vm->num_negated(consts[pos]);
|
||||
}
|
||||
}
|
||||
|
||||
// pre-compute sn in co_consts
|
||||
for(int i=0; i<consts.size(); i++){
|
||||
@ -525,17 +508,17 @@ inline f64 VM::num_to_float(PyObject* obj){
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline PyObject* VM::asBool(PyObject* obj){
|
||||
if(is_type(obj, tp_bool)) return obj;
|
||||
if(obj == None) return False;
|
||||
if(is_type(obj, tp_int)) return VAR(CAST(i64, obj) != 0);
|
||||
if(is_type(obj, tp_float)) return VAR(CAST(f64, obj) != 0.0);
|
||||
inline bool VM::asBool(PyObject* obj){
|
||||
if(is_type(obj, tp_bool)) return obj == True;
|
||||
if(obj == None) return false;
|
||||
if(is_type(obj, tp_int)) return CAST(i64, obj) != 0;
|
||||
if(is_type(obj, tp_float)) return CAST(f64, obj) != 0.0;
|
||||
PyObject* len_f = getattr(obj, __len__, false, true);
|
||||
if(len_f != nullptr){
|
||||
PyObject* ret = call(len_f, no_arg());
|
||||
return VAR(CAST(i64, ret) > 0);
|
||||
return CAST(i64, ret) > 0;
|
||||
}
|
||||
return True;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline i64 VM::hash(PyObject* obj){
|
||||
@ -617,11 +600,6 @@ inline Str VM::disassemble(CodeObject_ co){
|
||||
if(byte.op == OP_LOAD_NAME_REF || byte.op == OP_LOAD_NAME || byte.op == OP_RAISE || byte.op == OP_STORE_NAME){
|
||||
argStr += " (" + co->names[byte.arg].first.str().escape(true) + ")";
|
||||
}
|
||||
if(byte.op == OP_FAST_INDEX || byte.op == OP_FAST_INDEX_REF){
|
||||
auto& a = co->names[byte.arg & 0xFFFF];
|
||||
auto& x = co->names[(byte.arg >> 16) & 0xFFFF];
|
||||
argStr += " (" + a.first.str() + '[' + x.first.str() + "])";
|
||||
}
|
||||
ss << argStr;
|
||||
// ss << pad(argStr, 20); // may overflow
|
||||
// ss << co->blocks[byte.block].to_string();
|
||||
|
Loading…
x
Reference in New Issue
Block a user