some optimize

This commit is contained in:
blueloveTH 2023-02-18 21:12:32 +08:00
parent 30c673b875
commit cae01cb5b7
5 changed files with 48 additions and 24 deletions

View File

@ -42,6 +42,13 @@ PyVar VM::run_frame(Frame* frame){
if(byte.arg == 0) frame->push(PyRef(ref));
else frame->push(ref.get(this, frame));
} break;
case OP_FAST_INDEX: case OP_FAST_INDEX_REF: {
auto& a = frame->co->names[byte.arg & 0xFFFF];
auto& x = frame->co->names[(byte.arg >> 16) & 0xFFFF];
auto ref = IndexRef(NameRef(a).get(this, frame), NameRef(x).get(this, frame));
if(byte.op == OP_FAST_INDEX) frame->push(ref.get(this, frame));
else frame->push(PyRef(ref));
} break;
case OP_STORE_REF: {
PyVar obj = frame->pop_value(this);
PyVarRef r = frame->pop();
@ -205,7 +212,7 @@ PyVar VM::run_frame(Frame* frame){
PyVar obj = call(builtins->attr("set"), pkpy::one_arg(list));
frame->push(obj);
} break;
case OP_DUP_TOP: frame->push(frame->top_value(this)); break;
case OP_DUP_TOP_VALUE: frame->push(frame->top_value(this)); break;
case OP_CALL:
{
int ARGC = byte.arg & 0xFFFF;

View File

@ -406,7 +406,7 @@ private:
EXPR_TUPLE();
emit(OP_STORE_REF);
}else{ // a += (expr) -> a = a + (expr)
emit(OP_DUP_TOP);
emit(OP_DUP_TOP_VALUE);
EXPR();
switch (op) {
case TK("+="): emit(OP_BINARY_OP, 0); break;
@ -732,7 +732,7 @@ __LISTCOMP:
Token tkmodule = _compile_import();
consume(TK("import"));
do {
emit(OP_DUP_TOP);
emit(OP_DUP_TOP_VALUE);
consume(TK("@id"));
Token tkname = parser->prev;
int index = co()->add_name(tkname.str(), NAME_ATTR);

View File

@ -2,7 +2,7 @@
OPCODE(NO_OP)
OPCODE(POP_TOP)
OPCODE(DUP_TOP)
OPCODE(DUP_TOP_VALUE)
OPCODE(CALL)
OPCODE(RETURN_VALUE)
@ -69,7 +69,8 @@ OPCODE(TRY_BLOCK_ENTER)
OPCODE(TRY_BLOCK_EXIT)
OPCODE(YIELD_VALUE)
//OPCODE(FAST_INDEX_0) // a[0]
//OPCODE(FAST_INDEX_1) // a[i]
OPCODE(FAST_INDEX) // a[x]
OPCODE(FAST_INDEX_REF) // a[x]
#endif

View File

@ -184,7 +184,7 @@ void init_builtins(VM* _vm) {
if(flag) return vm->PyFloat((f64)(1.0 / ret));
return vm->PyInt(ret);
}else{
return vm->PyFloat((f64)pow(vm->num_to_float(args[0]), vm->num_to_float(args[1])));
return vm->PyFloat((f64)std::pow(vm->num_to_float(args[0]), vm->num_to_float(args[1])));
}
});
@ -220,26 +220,19 @@ void init_builtins(VM* _vm) {
return vm->PyInt(vm->PyInt_AS_C(args[0]) % rhs);
});
_vm->bind_method<0>("int", "__repr__", [](VM* vm, pkpy::Args& args) {
return vm->PyStr(std::to_string(vm->PyInt_AS_C(args[0])));
});
_vm->bind_method<0>("int", "__repr__", CPP_LAMBDA(vm->PyStr(std::to_string(vm->PyInt_AS_C(args[0])))));
_vm->bind_method<0>("int", "__json__", CPP_LAMBDA(vm->PyStr(std::to_string(vm->PyInt_AS_C(args[0])))));
_vm->bind_method<0>("int", "__json__", [](VM* vm, pkpy::Args& args) {
return vm->PyStr(std::to_string(vm->PyInt_AS_C(args[0])));
});
#define INT_BITWISE_OP(name,op) \
_vm->bind_method<1>("int", #name, CPP_LAMBDA(vm->PyInt(vm->PyInt_AS_C(args[0]) op vm->PyInt_AS_C(args[1]))));
#define __INT_BITWISE_OP(name,op) \
_vm->bind_method<1>("int", #name, [](VM* vm, pkpy::Args& args) { \
return vm->PyInt(vm->PyInt_AS_C(args[0]) op vm->PyInt_AS_C(args[1])); \
});
INT_BITWISE_OP(__lshift__, <<)
INT_BITWISE_OP(__rshift__, >>)
INT_BITWISE_OP(__and__, &)
INT_BITWISE_OP(__or__, |)
INT_BITWISE_OP(__xor__, ^)
__INT_BITWISE_OP(__lshift__, <<)
__INT_BITWISE_OP(__rshift__, >>)
__INT_BITWISE_OP(__and__, &)
__INT_BITWISE_OP(__or__, |)
__INT_BITWISE_OP(__xor__, ^)
#undef __INT_BITWISE_OP
#undef INT_BITWISE_OP
/************ PyFloat ************/
_vm->bind_static_method<1>("float", "__new__", [](VM* vm, pkpy::Args& args) {

View File

@ -464,6 +464,7 @@ public:
int prev_line = -1;
for(int i=0; i<co->codes.size(); i++){
const Bytecode& byte = co->codes[i];
if(byte.op == OP_NO_OP) continue;
Str line = std::to_string(byte.line);
if(byte.line == prev_line) line = "";
else{
@ -487,6 +488,11 @@ public:
if(byte.op == OP_LOAD_NAME_REF || byte.op == OP_LOAD_NAME || byte.op == OP_RAISE){
argStr += " (" + co->names[byte.arg].first.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 + '[' + x.first + "])";
}
ss << pad(argStr, 20); // may overflow
ss << co->blocks[byte.block].to_string();
if(i != co->codes.size() - 1) ss << '\n';
@ -835,5 +841,22 @@ void CodeObject::optimize(VM* vm){
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;
}
}
}