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)); if(byte.arg == 0) frame->push(PyRef(ref));
else frame->push(ref.get(this, frame)); else frame->push(ref.get(this, frame));
} break; } 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: { case OP_STORE_REF: {
PyVar obj = frame->pop_value(this); PyVar obj = frame->pop_value(this);
PyVarRef r = frame->pop(); PyVarRef r = frame->pop();
@ -205,7 +212,7 @@ PyVar VM::run_frame(Frame* frame){
PyVar obj = call(builtins->attr("set"), pkpy::one_arg(list)); PyVar obj = call(builtins->attr("set"), pkpy::one_arg(list));
frame->push(obj); frame->push(obj);
} break; } 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: case OP_CALL:
{ {
int ARGC = byte.arg & 0xFFFF; int ARGC = byte.arg & 0xFFFF;

View File

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

View File

@ -2,7 +2,7 @@
OPCODE(NO_OP) OPCODE(NO_OP)
OPCODE(POP_TOP) OPCODE(POP_TOP)
OPCODE(DUP_TOP) OPCODE(DUP_TOP_VALUE)
OPCODE(CALL) OPCODE(CALL)
OPCODE(RETURN_VALUE) OPCODE(RETURN_VALUE)
@ -69,7 +69,8 @@ OPCODE(TRY_BLOCK_ENTER)
OPCODE(TRY_BLOCK_EXIT) OPCODE(TRY_BLOCK_EXIT)
OPCODE(YIELD_VALUE) 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 #endif

View File

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

View File

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