|
@@ -11,6 +11,10 @@ inline PyObject* VM::_run_top_frame(){
|
|
|
const int base_id = frame.index;
|
|
const int base_id = frame.index;
|
|
|
bool need_raise = false;
|
|
bool need_raise = false;
|
|
|
|
|
|
|
|
|
|
+ // shared registers
|
|
|
|
|
+ PyObject *_0, *_1, *_2;
|
|
|
|
|
+ StrName _name;
|
|
|
|
|
+
|
|
|
while(true){
|
|
while(true){
|
|
|
#if DEBUG_EXTRA_CHECK
|
|
#if DEBUG_EXTRA_CHECK
|
|
|
if(frame.index < base_id) FATAL_ERROR();
|
|
if(frame.index < base_id) FATAL_ERROR();
|
|
@@ -21,8 +25,6 @@ inline PyObject* VM::_run_top_frame(){
|
|
|
/* NOTE:
|
|
/* NOTE:
|
|
|
* Be aware of accidental gc!
|
|
* Be aware of accidental gc!
|
|
|
* DO NOT leave any strong reference of PyObject* in the C stack
|
|
* DO NOT leave any strong reference of PyObject* in the C stack
|
|
|
- * For example, POPX() returns a strong reference which may be dangerous
|
|
|
|
|
- * `Args` containing strong references is safe if it is passed to `call` or `fast_call`
|
|
|
|
|
*/
|
|
*/
|
|
|
{
|
|
{
|
|
|
#define DISPATCH_OP_CALL() { frame = top_frame(); goto __NEXT_FRAME; }
|
|
#define DISPATCH_OP_CALL() { frame = top_frame(); goto __NEXT_FRAME; }
|
|
@@ -63,11 +65,10 @@ __NEXT_STEP:;
|
|
|
TARGET(POP_TOP) POP(); DISPATCH();
|
|
TARGET(POP_TOP) POP(); DISPATCH();
|
|
|
TARGET(DUP_TOP) PUSH(TOP()); DISPATCH();
|
|
TARGET(DUP_TOP) PUSH(TOP()); DISPATCH();
|
|
|
TARGET(ROT_TWO) std::swap(TOP(), SECOND()); DISPATCH();
|
|
TARGET(ROT_TWO) std::swap(TOP(), SECOND()); DISPATCH();
|
|
|
- TARGET(PRINT_EXPR) {
|
|
|
|
|
- PyObject* obj = TOP(); // use top() to avoid accidental gc
|
|
|
|
|
- if(obj != None) *_stdout << CAST(Str&, asRepr(obj)) << '\n';
|
|
|
|
|
|
|
+ TARGET(PRINT_EXPR)
|
|
|
|
|
+ if(TOP() != None) *_stdout << CAST(Str&, asRepr(TOP())) << '\n';
|
|
|
POP();
|
|
POP();
|
|
|
- } DISPATCH();
|
|
|
|
|
|
|
+ DISPATCH();
|
|
|
/*****************************************/
|
|
/*****************************************/
|
|
|
TARGET(LOAD_CONST)
|
|
TARGET(LOAD_CONST)
|
|
|
heap._auto_collect();
|
|
heap._auto_collect();
|
|
@@ -93,134 +94,127 @@ __NEXT_STEP:;
|
|
|
/*****************************************/
|
|
/*****************************************/
|
|
|
TARGET(LOAD_FAST) {
|
|
TARGET(LOAD_FAST) {
|
|
|
heap._auto_collect();
|
|
heap._auto_collect();
|
|
|
- PyObject* val = frame->_locals[byte.arg];
|
|
|
|
|
- if(val == nullptr) vm->NameError(co->varnames[byte.arg]);
|
|
|
|
|
- PUSH(val);
|
|
|
|
|
|
|
+ _0 = frame->_locals[byte.arg];
|
|
|
|
|
+ if(_0 == nullptr) vm->NameError(co->varnames[byte.arg]);
|
|
|
|
|
+ PUSH(_0);
|
|
|
} DISPATCH();
|
|
} DISPATCH();
|
|
|
- TARGET(LOAD_NAME) {
|
|
|
|
|
|
|
+ TARGET(LOAD_NAME)
|
|
|
heap._auto_collect();
|
|
heap._auto_collect();
|
|
|
- StrName name(byte.arg);
|
|
|
|
|
- PyObject* val;
|
|
|
|
|
- val = frame->_locals.try_get(name);
|
|
|
|
|
- if(val != nullptr) { PUSH(val); DISPATCH(); }
|
|
|
|
|
- val = frame->_closure.try_get(name);
|
|
|
|
|
- if(val != nullptr) { PUSH(val); DISPATCH(); }
|
|
|
|
|
- val = frame->f_globals().try_get(name);
|
|
|
|
|
- if(val != nullptr) { PUSH(val); DISPATCH(); }
|
|
|
|
|
- val = vm->builtins->attr().try_get(name);
|
|
|
|
|
- if(val != nullptr) { PUSH(val); DISPATCH(); }
|
|
|
|
|
- vm->NameError(name);
|
|
|
|
|
- } DISPATCH();
|
|
|
|
|
|
|
+ _name = StrName(byte.arg);
|
|
|
|
|
+ _0 = frame->_locals.try_get(_name);
|
|
|
|
|
+ if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
|
|
|
|
|
+ _0 = frame->_closure.try_get(_name);
|
|
|
|
|
+ if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
|
|
|
|
|
+ _0 = frame->f_globals().try_get(_name);
|
|
|
|
|
+ if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
|
|
|
|
|
+ _0 = vm->builtins->attr().try_get(_name);
|
|
|
|
|
+ if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
|
|
|
|
|
+ vm->NameError(_name);
|
|
|
|
|
+ DISPATCH();
|
|
|
TARGET(LOAD_NONLOCAL) {
|
|
TARGET(LOAD_NONLOCAL) {
|
|
|
heap._auto_collect();
|
|
heap._auto_collect();
|
|
|
- StrName name(byte.arg);
|
|
|
|
|
- PyObject* val;
|
|
|
|
|
- val = frame->_closure.try_get(name);
|
|
|
|
|
- if(val != nullptr) { PUSH(val); DISPATCH(); }
|
|
|
|
|
- val = frame->f_globals().try_get(name);
|
|
|
|
|
- if(val != nullptr) { PUSH(val); DISPATCH(); }
|
|
|
|
|
- val = vm->builtins->attr().try_get(name);
|
|
|
|
|
- if(val != nullptr) { PUSH(val); DISPATCH(); }
|
|
|
|
|
- vm->NameError(name);
|
|
|
|
|
|
|
+ _name = StrName(byte.arg);
|
|
|
|
|
+ // _0 = frame->_locals.try_get(_name);
|
|
|
|
|
+ // if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
|
|
|
|
|
+ _0 = frame->_closure.try_get(_name);
|
|
|
|
|
+ if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
|
|
|
|
|
+ _0 = frame->f_globals().try_get(_name);
|
|
|
|
|
+ if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
|
|
|
|
|
+ _0 = vm->builtins->attr().try_get(_name);
|
|
|
|
|
+ if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
|
|
|
|
|
+ vm->NameError(_name);
|
|
|
|
|
+ DISPATCH();
|
|
|
} DISPATCH();
|
|
} DISPATCH();
|
|
|
- TARGET(LOAD_GLOBAL) {
|
|
|
|
|
|
|
+ TARGET(LOAD_GLOBAL)
|
|
|
heap._auto_collect();
|
|
heap._auto_collect();
|
|
|
- StrName name(byte.arg);
|
|
|
|
|
- PyObject* val = frame->f_globals().try_get(name);
|
|
|
|
|
- if(val != nullptr) { PUSH(val); DISPATCH(); }
|
|
|
|
|
- val = vm->builtins->attr().try_get(name);
|
|
|
|
|
- if(val != nullptr) { PUSH(val); DISPATCH(); }
|
|
|
|
|
- vm->NameError(name);
|
|
|
|
|
- } DISPATCH();
|
|
|
|
|
- TARGET(LOAD_ATTR) {
|
|
|
|
|
- PyObject* a = TOP();
|
|
|
|
|
- StrName name(byte.arg);
|
|
|
|
|
- TOP() = getattr(a, name);
|
|
|
|
|
- } DISPATCH();
|
|
|
|
|
- TARGET(LOAD_METHOD) {
|
|
|
|
|
- PyObject* a = TOP();
|
|
|
|
|
- StrName name(byte.arg);
|
|
|
|
|
- PyObject* self;
|
|
|
|
|
- TOP() = get_unbound_method(a, name, &self, true, true);
|
|
|
|
|
- PUSH(self);
|
|
|
|
|
- } DISPATCH();
|
|
|
|
|
- TARGET(LOAD_SUBSCR) {
|
|
|
|
|
- PyObject* b = POPX();
|
|
|
|
|
- PyObject* a = TOP();
|
|
|
|
|
- TOP() = call_method(a, __getitem__, b);
|
|
|
|
|
- } DISPATCH();
|
|
|
|
|
|
|
+ _name = StrName(byte.arg);
|
|
|
|
|
+ _0 = frame->f_globals().try_get(_name);
|
|
|
|
|
+ if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
|
|
|
|
|
+ _0 = vm->builtins->attr().try_get(_name);
|
|
|
|
|
+ if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
|
|
|
|
|
+ vm->NameError(_name);
|
|
|
|
|
+ DISPATCH();
|
|
|
|
|
+ TARGET(LOAD_ATTR)
|
|
|
|
|
+ TOP() = getattr(TOP(), StrName(byte.arg));
|
|
|
|
|
+ DISPATCH();
|
|
|
|
|
+ TARGET(LOAD_METHOD)
|
|
|
|
|
+ TOP() = get_unbound_method(TOP(), StrName(byte.arg), &_0, true, true);
|
|
|
|
|
+ PUSH(_0);
|
|
|
|
|
+ DISPATCH();
|
|
|
|
|
+ TARGET(LOAD_SUBSCR)
|
|
|
|
|
+ _1 = POPX();
|
|
|
|
|
+ _0 = TOP();
|
|
|
|
|
+ TOP() = call_method(_0, __getitem__, _1);
|
|
|
|
|
+ DISPATCH();
|
|
|
TARGET(STORE_FAST)
|
|
TARGET(STORE_FAST)
|
|
|
frame->_locals[byte.arg] = POPX();
|
|
frame->_locals[byte.arg] = POPX();
|
|
|
DISPATCH();
|
|
DISPATCH();
|
|
|
- TARGET(STORE_NAME) {
|
|
|
|
|
- StrName name(byte.arg);
|
|
|
|
|
- PyObject* val = POPX();
|
|
|
|
|
|
|
+ TARGET(STORE_NAME)
|
|
|
|
|
+ _name = StrName(byte.arg);
|
|
|
|
|
+ _0 = POPX();
|
|
|
if(frame->_locals.is_valid()){
|
|
if(frame->_locals.is_valid()){
|
|
|
- bool ok = frame->_locals.try_set(name, val);
|
|
|
|
|
- if(!ok) vm->NameError(name);
|
|
|
|
|
|
|
+ bool ok = frame->_locals.try_set(_name, _0);
|
|
|
|
|
+ if(!ok) vm->NameError(_name);
|
|
|
}else{
|
|
}else{
|
|
|
- frame->f_globals().set(name, val);
|
|
|
|
|
|
|
+ frame->f_globals().set(_name, _0);
|
|
|
}
|
|
}
|
|
|
- } DISPATCH();
|
|
|
|
|
- TARGET(STORE_GLOBAL) {
|
|
|
|
|
- StrName name(byte.arg);
|
|
|
|
|
- frame->f_globals().set(name, POPX());
|
|
|
|
|
- } DISPATCH();
|
|
|
|
|
|
|
+ DISPATCH();
|
|
|
|
|
+ TARGET(STORE_GLOBAL)
|
|
|
|
|
+ frame->f_globals().set(StrName(byte.arg), POPX());
|
|
|
|
|
+ DISPATCH();
|
|
|
TARGET(STORE_ATTR) {
|
|
TARGET(STORE_ATTR) {
|
|
|
- StrName name(byte.arg);
|
|
|
|
|
- PyObject* a = TOP();
|
|
|
|
|
- PyObject* val = SECOND();
|
|
|
|
|
- setattr(a, name, val);
|
|
|
|
|
|
|
+ _0 = TOP(); // a
|
|
|
|
|
+ _1 = SECOND(); // val
|
|
|
|
|
+ setattr(_0, StrName(byte.arg), _1);
|
|
|
STACK_SHRINK(2);
|
|
STACK_SHRINK(2);
|
|
|
} DISPATCH();
|
|
} DISPATCH();
|
|
|
- TARGET(STORE_SUBSCR) {
|
|
|
|
|
- // val a b
|
|
|
|
|
- PyObject* b = POPX();
|
|
|
|
|
- PyObject* a = POPX();
|
|
|
|
|
- PyObject* val = POPX();
|
|
|
|
|
- call_method(a, __setitem__, b, val);
|
|
|
|
|
- } DISPATCH();
|
|
|
|
|
- TARGET(DELETE_FAST) {
|
|
|
|
|
- PyObject* val = frame->_locals[byte.arg];
|
|
|
|
|
- if(val == nullptr) vm->NameError(co->varnames[byte.arg]);
|
|
|
|
|
|
|
+ TARGET(STORE_SUBSCR)
|
|
|
|
|
+ _2 = POPX(); // b
|
|
|
|
|
+ _1 = POPX(); // a
|
|
|
|
|
+ _0 = POPX(); // val
|
|
|
|
|
+ call_method(_1, __setitem__, _2, _0);
|
|
|
|
|
+ DISPATCH();
|
|
|
|
|
+ TARGET(DELETE_FAST)
|
|
|
|
|
+ _0 = frame->_locals[byte.arg];
|
|
|
|
|
+ if(_0 == nullptr) vm->NameError(co->varnames[byte.arg]);
|
|
|
frame->_locals[byte.arg] = nullptr;
|
|
frame->_locals[byte.arg] = nullptr;
|
|
|
- } DISPATCH();
|
|
|
|
|
- TARGET(DELETE_NAME) {
|
|
|
|
|
- StrName name(byte.arg);
|
|
|
|
|
|
|
+ DISPATCH();
|
|
|
|
|
+ TARGET(DELETE_NAME)
|
|
|
|
|
+ _name = StrName(byte.arg);
|
|
|
if(frame->_locals.is_valid()){
|
|
if(frame->_locals.is_valid()){
|
|
|
- if(!frame->_locals.contains(name)) vm->NameError(name);
|
|
|
|
|
- frame->_locals.erase(name);
|
|
|
|
|
|
|
+ if(!frame->_locals.contains(_name)) vm->NameError(_name);
|
|
|
|
|
+ frame->_locals.erase(_name);
|
|
|
}else{
|
|
}else{
|
|
|
- if(!frame->f_globals().contains(name)) vm->NameError(name);
|
|
|
|
|
- frame->f_globals().erase(name);
|
|
|
|
|
|
|
+ if(!frame->f_globals().contains(_name)) vm->NameError(_name);
|
|
|
|
|
+ frame->f_globals().erase(_name);
|
|
|
}
|
|
}
|
|
|
- } DISPATCH();
|
|
|
|
|
- TARGET(DELETE_GLOBAL) {
|
|
|
|
|
- StrName name(byte.arg);
|
|
|
|
|
- if(frame->f_globals().contains(name)){
|
|
|
|
|
- frame->f_globals().erase(name);
|
|
|
|
|
|
|
+ DISPATCH();
|
|
|
|
|
+ TARGET(DELETE_GLOBAL)
|
|
|
|
|
+ _name = StrName(byte.arg);
|
|
|
|
|
+ if(frame->f_globals().contains(_name)){
|
|
|
|
|
+ frame->f_globals().erase(_name);
|
|
|
}else{
|
|
}else{
|
|
|
- NameError(name);
|
|
|
|
|
|
|
+ NameError(_name);
|
|
|
}
|
|
}
|
|
|
- } DISPATCH();
|
|
|
|
|
- TARGET(DELETE_ATTR) {
|
|
|
|
|
- PyObject* a = POPX();
|
|
|
|
|
- StrName name(byte.arg);
|
|
|
|
|
- if(!a->is_attr_valid()) TypeError("cannot delete attribute");
|
|
|
|
|
- if(!a->attr().contains(name)) AttributeError(a, name);
|
|
|
|
|
- a->attr().erase(name);
|
|
|
|
|
- } DISPATCH();
|
|
|
|
|
- TARGET(DELETE_SUBSCR) {
|
|
|
|
|
- PyObject* b = POPX();
|
|
|
|
|
- PyObject* a = POPX();
|
|
|
|
|
- call_method(a, __delitem__, b);
|
|
|
|
|
- } DISPATCH();
|
|
|
|
|
|
|
+ DISPATCH();
|
|
|
|
|
+ TARGET(DELETE_ATTR)
|
|
|
|
|
+ _0 = POPX();
|
|
|
|
|
+ _name = StrName(byte.arg);
|
|
|
|
|
+ if(!_0->is_attr_valid()) TypeError("cannot delete attribute");
|
|
|
|
|
+ if(!_0->attr().contains(_name)) AttributeError(_0, _name);
|
|
|
|
|
+ _0->attr().erase(_name);
|
|
|
|
|
+ DISPATCH();
|
|
|
|
|
+ TARGET(DELETE_SUBSCR)
|
|
|
|
|
+ _1 = POPX();
|
|
|
|
|
+ _0 = POPX();
|
|
|
|
|
+ call_method(_0, __delitem__, _1);
|
|
|
|
|
+ DISPATCH();
|
|
|
/*****************************************/
|
|
/*****************************************/
|
|
|
- TARGET(BUILD_LIST) {
|
|
|
|
|
- PyObject* obj = VAR(STACK_VIEW(byte.arg).to_list());
|
|
|
|
|
|
|
+ TARGET(BUILD_LIST)
|
|
|
|
|
+ _0 = VAR(STACK_VIEW(byte.arg).to_list());
|
|
|
STACK_SHRINK(byte.arg);
|
|
STACK_SHRINK(byte.arg);
|
|
|
- PUSH(obj);
|
|
|
|
|
- } DISPATCH();
|
|
|
|
|
|
|
+ PUSH(_0);
|
|
|
|
|
+ DISPATCH();
|
|
|
TARGET(BUILD_DICT) {
|
|
TARGET(BUILD_DICT) {
|
|
|
PyObject* t = VAR(STACK_VIEW(byte.arg).to_tuple());
|
|
PyObject* t = VAR(STACK_VIEW(byte.arg).to_tuple());
|
|
|
PyObject* obj = call_(builtins->attr(m_dict), t);
|
|
PyObject* obj = call_(builtins->attr(m_dict), t);
|
|
@@ -234,20 +228,20 @@ __NEXT_STEP:;
|
|
|
PUSH(obj);
|
|
PUSH(obj);
|
|
|
} DISPATCH();
|
|
} DISPATCH();
|
|
|
TARGET(BUILD_SLICE) {
|
|
TARGET(BUILD_SLICE) {
|
|
|
- PyObject* step = POPX();
|
|
|
|
|
- PyObject* stop = POPX();
|
|
|
|
|
- PyObject* start = POPX();
|
|
|
|
|
|
|
+ _2 = POPX();
|
|
|
|
|
+ _1 = POPX();
|
|
|
|
|
+ _0 = POPX();
|
|
|
Slice s;
|
|
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(_0 != None) s.start = CAST(int, _0);
|
|
|
|
|
+ if(_1 != None) s.stop = CAST(int, _1);
|
|
|
|
|
+ if(_2 != None) s.step = CAST(int, _2);
|
|
|
PUSH(VAR(s));
|
|
PUSH(VAR(s));
|
|
|
} DISPATCH();
|
|
} DISPATCH();
|
|
|
- TARGET(BUILD_TUPLE) {
|
|
|
|
|
- PyObject* obj = VAR(STACK_VIEW(byte.arg).to_tuple());
|
|
|
|
|
|
|
+ TARGET(BUILD_TUPLE)
|
|
|
|
|
+ _0 = VAR(STACK_VIEW(byte.arg).to_tuple());
|
|
|
STACK_SHRINK(byte.arg);
|
|
STACK_SHRINK(byte.arg);
|
|
|
- PUSH(obj);
|
|
|
|
|
- } DISPATCH();
|
|
|
|
|
|
|
+ PUSH(_0);
|
|
|
|
|
+ DISPATCH();
|
|
|
TARGET(BUILD_STRING) {
|
|
TARGET(BUILD_STRING) {
|
|
|
std::stringstream ss;
|
|
std::stringstream ss;
|
|
|
auto view = STACK_VIEW(byte.arg);
|
|
auto view = STACK_VIEW(byte.arg);
|
|
@@ -256,11 +250,11 @@ __NEXT_STEP:;
|
|
|
PUSH(VAR(ss.str()));
|
|
PUSH(VAR(ss.str()));
|
|
|
} DISPATCH();
|
|
} DISPATCH();
|
|
|
/*****************************************/
|
|
/*****************************************/
|
|
|
- TARGET(BINARY_OP) {
|
|
|
|
|
- PyObject* b = POPX();
|
|
|
|
|
- PyObject* a = TOP();
|
|
|
|
|
- TOP() = call_method(a, BINARY_SPECIAL_METHODS[byte.arg], b);
|
|
|
|
|
- } DISPATCH();
|
|
|
|
|
|
|
+ TARGET(BINARY_OP)
|
|
|
|
|
+ _1 = POPX(); // b
|
|
|
|
|
+ _0 = TOP(); // a
|
|
|
|
|
+ TOP() = call_method(_0, BINARY_SPECIAL_METHODS[byte.arg], _1);
|
|
|
|
|
+ DISPATCH();
|
|
|
|
|
|
|
|
#define INT_BINARY_OP(op, func) \
|
|
#define INT_BINARY_OP(op, func) \
|
|
|
if(is_both_int(TOP(), SECOND())){ \
|
|
if(is_both_int(TOP(), SECOND())){ \
|
|
@@ -269,9 +263,9 @@ __NEXT_STEP:;
|
|
|
POP(); \
|
|
POP(); \
|
|
|
TOP() = VAR(a op b); \
|
|
TOP() = VAR(a op b); \
|
|
|
}else{ \
|
|
}else{ \
|
|
|
- PyObject* b = POPX(); \
|
|
|
|
|
- PyObject* a = TOP(); \
|
|
|
|
|
- TOP() = call_method(a, func, b); \
|
|
|
|
|
|
|
+ _1 = POPX(); \
|
|
|
|
|
+ _0 = TOP(); \
|
|
|
|
|
+ TOP() = call_method(_0, func, _1); \
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
TARGET(BINARY_ADD)
|
|
TARGET(BINARY_ADD)
|
|
@@ -323,22 +317,29 @@ __NEXT_STEP:;
|
|
|
INT_BINARY_OP(^, __xor__)
|
|
INT_BINARY_OP(^, __xor__)
|
|
|
DISPATCH()
|
|
DISPATCH()
|
|
|
#undef INT_BINARY_OP
|
|
#undef INT_BINARY_OP
|
|
|
- TARGET(IS_OP) {
|
|
|
|
|
- PyObject* rhs = POPX();
|
|
|
|
|
- PyObject* lhs = TOP();
|
|
|
|
|
- bool ret_c = lhs == rhs;
|
|
|
|
|
- if(byte.arg == 1) ret_c = !ret_c;
|
|
|
|
|
- TOP() = VAR(ret_c);
|
|
|
|
|
- } DISPATCH();
|
|
|
|
|
- TARGET(CONTAINS_OP) {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ TARGET(IS_OP)
|
|
|
|
|
+ _1 = POPX(); // rhs
|
|
|
|
|
+ _0 = TOP(); // lhs
|
|
|
|
|
+ if(byte.arg == 1){
|
|
|
|
|
+ TOP() = VAR(_0 != _1);
|
|
|
|
|
+ }else{
|
|
|
|
|
+ TOP() = VAR(_0 == _1);
|
|
|
|
|
+ }
|
|
|
|
|
+ DISPATCH();
|
|
|
|
|
+ TARGET(CONTAINS_OP)
|
|
|
// a in b -> b __contains__ a
|
|
// a in b -> b __contains__ a
|
|
|
- PyObject* ret = call_method(TOP(), __contains__, SECOND());
|
|
|
|
|
- bool ret_c = CAST(bool, ret);
|
|
|
|
|
- if(byte.arg == 1) ret_c = !ret_c;
|
|
|
|
|
- TOP() = VAR(ret_c);
|
|
|
|
|
- } DISPATCH();
|
|
|
|
|
|
|
+ _0 = call_method(TOP(), __contains__, SECOND());
|
|
|
|
|
+ if(byte.arg == 1){
|
|
|
|
|
+ TOP() = VAR(!CAST(bool, _0));
|
|
|
|
|
+ }else{
|
|
|
|
|
+ TOP() = VAR(CAST(bool, _0));
|
|
|
|
|
+ }
|
|
|
|
|
+ DISPATCH();
|
|
|
/*****************************************/
|
|
/*****************************************/
|
|
|
- TARGET(JUMP_ABSOLUTE) frame->jump_abs(byte.arg); DISPATCH();
|
|
|
|
|
|
|
+ TARGET(JUMP_ABSOLUTE)
|
|
|
|
|
+ frame->jump_abs(byte.arg);
|
|
|
|
|
+ DISPATCH();
|
|
|
TARGET(POP_JUMP_IF_FALSE)
|
|
TARGET(POP_JUMP_IF_FALSE)
|
|
|
if(!asBool(POPX())) frame->jump_abs(byte.arg);
|
|
if(!asBool(POPX())) frame->jump_abs(byte.arg);
|
|
|
DISPATCH();
|
|
DISPATCH();
|
|
@@ -354,10 +355,11 @@ __NEXT_STEP:;
|
|
|
int target = co_blocks[byte.block].start;
|
|
int target = co_blocks[byte.block].start;
|
|
|
frame->jump_abs(target);
|
|
frame->jump_abs(target);
|
|
|
} DISPATCH();
|
|
} DISPATCH();
|
|
|
- TARGET(LOOP_BREAK) {
|
|
|
|
|
- int target = co_blocks[byte.block].end;
|
|
|
|
|
- frame->jump_abs_break(target);
|
|
|
|
|
- } DISPATCH();
|
|
|
|
|
|
|
+ TARGET(LOOP_BREAK)
|
|
|
|
|
+ frame->jump_abs_break(
|
|
|
|
|
+ co_blocks[byte.block].end
|
|
|
|
|
+ );
|
|
|
|
|
+ DISPATCH();
|
|
|
TARGET(GOTO) {
|
|
TARGET(GOTO) {
|
|
|
StrName name(byte.arg);
|
|
StrName name(byte.arg);
|
|
|
int index = co->labels->try_get(name);
|
|
int index = co->labels->try_get(name);
|
|
@@ -368,27 +370,27 @@ __NEXT_STEP:;
|
|
|
TARGET(BEGIN_CALL)
|
|
TARGET(BEGIN_CALL)
|
|
|
PUSH(_py_begin_call);
|
|
PUSH(_py_begin_call);
|
|
|
DISPATCH();
|
|
DISPATCH();
|
|
|
- TARGET(CALL) {
|
|
|
|
|
- int ARGC = byte.arg & 0xFFFF;
|
|
|
|
|
- int KWARGC = (byte.arg >> 16) & 0xFFFF;
|
|
|
|
|
- PyObject* ret = _vectorcall(ARGC, KWARGC, true);
|
|
|
|
|
- if(ret == _py_op_call) { DISPATCH_OP_CALL(); }
|
|
|
|
|
- PUSH(ret);
|
|
|
|
|
|
|
+ TARGET(CALL)
|
|
|
|
|
+ _0 = _vectorcall(
|
|
|
|
|
+ byte.arg & 0xFFFF, // ARGC
|
|
|
|
|
+ (byte.arg>>16) & 0xFFFF, // KWARGC
|
|
|
|
|
+ true
|
|
|
|
|
+ );
|
|
|
|
|
+ if(_0 == _py_op_call) DISPATCH_OP_CALL();
|
|
|
|
|
+ PUSH(_0);
|
|
|
DISPATCH();
|
|
DISPATCH();
|
|
|
- }
|
|
|
|
|
- TARGET(RETURN_VALUE) {
|
|
|
|
|
- PyObject* __ret = POPX();
|
|
|
|
|
|
|
+ TARGET(RETURN_VALUE)
|
|
|
|
|
+ _0 = POPX();
|
|
|
// cleanup the stack on return
|
|
// cleanup the stack on return
|
|
|
callstack.pop();
|
|
callstack.pop();
|
|
|
s_data.reset(frame->_sp_base);
|
|
s_data.reset(frame->_sp_base);
|
|
|
if(frame.index == base_id){ // [ frameBase<- ]
|
|
if(frame.index == base_id){ // [ frameBase<- ]
|
|
|
- return __ret;
|
|
|
|
|
|
|
+ return _0;
|
|
|
}else{
|
|
}else{
|
|
|
frame = top_frame();
|
|
frame = top_frame();
|
|
|
- PUSH(__ret);
|
|
|
|
|
|
|
+ PUSH(_0);
|
|
|
goto __NEXT_FRAME;
|
|
goto __NEXT_FRAME;
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
TARGET(YIELD_VALUE)
|
|
TARGET(YIELD_VALUE)
|
|
|
return _py_op_yield;
|
|
return _py_op_yield;
|
|
|
/*****************************************/
|
|
/*****************************************/
|
|
@@ -423,9 +425,9 @@ __NEXT_STEP:;
|
|
|
DISPATCH();
|
|
DISPATCH();
|
|
|
TARGET(FOR_ITER) {
|
|
TARGET(FOR_ITER) {
|
|
|
BaseIter* it = PyIter_AS_C(TOP());
|
|
BaseIter* it = PyIter_AS_C(TOP());
|
|
|
- PyObject* obj = it->next();
|
|
|
|
|
- if(obj != nullptr){
|
|
|
|
|
- PUSH(obj);
|
|
|
|
|
|
|
+ _0 = it->next();
|
|
|
|
|
+ if(_0 != nullptr){
|
|
|
|
|
+ PUSH(_0);
|
|
|
}else{
|
|
}else{
|
|
|
int target = co_blocks[byte.block].end;
|
|
int target = co_blocks[byte.block].end;
|
|
|
frame->jump_abs_break(target);
|
|
frame->jump_abs_break(target);
|