|
|
@@ -86,19 +86,22 @@ namespace pkpy{
|
|
|
return index;
|
|
|
}
|
|
|
|
|
|
+ int CodeEmitContext::add_const_string(std::string_view key){
|
|
|
+ auto it = _co_consts_string_dedup_map.find(key);
|
|
|
+ if(it != _co_consts_string_dedup_map.end()){
|
|
|
+ return it->second;
|
|
|
+ }else{
|
|
|
+ co->consts.push_back(VAR(key));
|
|
|
+ int index = co->consts.size() - 1;
|
|
|
+ _co_consts_string_dedup_map[std::string(key)] = index;
|
|
|
+ return index;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
int CodeEmitContext::add_const(PyObject* v){
|
|
|
if(is_non_tagged_type(v, vm->tp_str)){
|
|
|
- // string deduplication
|
|
|
- std::string_view key = PK_OBJ_GET(Str, v).sv();
|
|
|
- auto it = _co_consts_string_dedup_map.find(key);
|
|
|
- if(it != _co_consts_string_dedup_map.end()){
|
|
|
- return it->second;
|
|
|
- }else{
|
|
|
- co->consts.push_back(v);
|
|
|
- int index = co->consts.size() - 1;
|
|
|
- _co_consts_string_dedup_map[std::string(key)] = index;
|
|
|
- return index;
|
|
|
- }
|
|
|
+ // warning: should use add_const_string() instead
|
|
|
+ return add_const_string(PK_OBJ_GET(Str, v).sv());
|
|
|
}else{
|
|
|
// non-string deduplication
|
|
|
auto it = _co_consts_nonstring_dedup_map.find(v);
|
|
|
@@ -225,8 +228,7 @@ namespace pkpy{
|
|
|
}
|
|
|
|
|
|
void LongExpr::emit_(CodeEmitContext* ctx) {
|
|
|
- VM* vm = ctx->vm;
|
|
|
- ctx->emit_(OP_LOAD_CONST, ctx->add_const(VAR(s)), line);
|
|
|
+ ctx->emit_(OP_LOAD_CONST, ctx->add_const_string(s.sv()), line);
|
|
|
ctx->emit_(OP_BUILD_LONG, BC_NOARG, line);
|
|
|
}
|
|
|
|
|
|
@@ -237,31 +239,31 @@ namespace pkpy{
|
|
|
}
|
|
|
|
|
|
void BytesExpr::emit_(CodeEmitContext* ctx) {
|
|
|
- VM* vm = ctx->vm;
|
|
|
- ctx->emit_(OP_LOAD_CONST, ctx->add_const(VAR(s)), line);
|
|
|
+ ctx->emit_(OP_LOAD_CONST, ctx->add_const_string(s.sv()), line);
|
|
|
ctx->emit_(OP_BUILD_BYTES, BC_NOARG, line);
|
|
|
}
|
|
|
|
|
|
void LiteralExpr::emit_(CodeEmitContext* ctx) {
|
|
|
VM* vm = ctx->vm;
|
|
|
- PyObject* obj = nullptr;
|
|
|
if(std::holds_alternative<i64>(value)){
|
|
|
i64 _val = std::get<i64>(value);
|
|
|
if(is_imm_int(_val)){
|
|
|
ctx->emit_(OP_LOAD_INTEGER, (uint16_t)_val, line);
|
|
|
return;
|
|
|
}
|
|
|
- obj = VAR(_val);
|
|
|
+ ctx->emit_(OP_LOAD_CONST, ctx->add_const(VAR(_val)), line);
|
|
|
+ return;
|
|
|
}
|
|
|
if(std::holds_alternative<f64>(value)){
|
|
|
f64 _val = std::get<f64>(value);
|
|
|
- obj = VAR(_val);
|
|
|
+ ctx->emit_(OP_LOAD_CONST, ctx->add_const(VAR(_val)), line);
|
|
|
+ return;
|
|
|
}
|
|
|
if(std::holds_alternative<Str>(value)){
|
|
|
- obj = VAR(std::get<Str>(value));
|
|
|
+ std::string_view key = std::get<Str>(value).sv();
|
|
|
+ ctx->emit_(OP_LOAD_CONST, ctx->add_const_string(key), line);
|
|
|
+ return;
|
|
|
}
|
|
|
- PK_ASSERT(obj != nullptr)
|
|
|
- ctx->emit_(OP_LOAD_CONST, ctx->add_const(obj), line);
|
|
|
}
|
|
|
|
|
|
void NegatedExpr::emit_(CodeEmitContext* ctx){
|
|
|
@@ -412,7 +414,7 @@ namespace pkpy{
|
|
|
ctx->emit_(OP_LOAD_ATTR, attr.index, line);
|
|
|
}
|
|
|
}else{
|
|
|
- int index = ctx->add_const(py_var(ctx->vm, expr));
|
|
|
+ int index = ctx->add_const_string(expr.sv());
|
|
|
ctx->emit_(OP_FSTRING_EVAL, index, line);
|
|
|
}
|
|
|
if(repr){
|
|
|
@@ -421,7 +423,6 @@ namespace pkpy{
|
|
|
}
|
|
|
|
|
|
void FStringExpr::emit_(CodeEmitContext* ctx){
|
|
|
- VM* vm = ctx->vm;
|
|
|
int i = 0; // left index
|
|
|
int j = 0; // right index
|
|
|
int count = 0; // how many string parts
|
|
|
@@ -444,7 +445,7 @@ namespace pkpy{
|
|
|
for(char c: spec) if(!fmt_valid_char_set.count(c)){ ok = false; break; }
|
|
|
if(ok){
|
|
|
_load_simple_expr(ctx, expr.substr(0, conon));
|
|
|
- ctx->emit_(OP_FORMAT_STRING, ctx->add_const(VAR(spec)), line);
|
|
|
+ ctx->emit_(OP_FORMAT_STRING, ctx->add_const_string(spec.sv()), line);
|
|
|
}else{
|
|
|
// ':' is not a spec indicator
|
|
|
_load_simple_expr(ctx, expr);
|
|
|
@@ -461,7 +462,7 @@ namespace pkpy{
|
|
|
if(j+1 < src.size && src[j+1] == '{'){
|
|
|
// {{ -> {
|
|
|
j++;
|
|
|
- ctx->emit_(OP_LOAD_CONST, ctx->add_const(VAR("{")), line);
|
|
|
+ ctx->emit_(OP_LOAD_CONST, ctx->add_const_string("{"), line);
|
|
|
count++;
|
|
|
}else{
|
|
|
// { -> }
|
|
|
@@ -473,7 +474,7 @@ namespace pkpy{
|
|
|
if(j+1 < src.size && src[j+1] == '}'){
|
|
|
// }} -> }
|
|
|
j++;
|
|
|
- ctx->emit_(OP_LOAD_CONST, ctx->add_const(VAR("}")), line);
|
|
|
+ ctx->emit_(OP_LOAD_CONST, ctx->add_const_string("}"), line);
|
|
|
count++;
|
|
|
}else{
|
|
|
// } -> error
|
|
|
@@ -485,7 +486,7 @@ namespace pkpy{
|
|
|
i = j;
|
|
|
while(j < src.size && src[j] != '{' && src[j] != '}') j++;
|
|
|
Str literal = src.substr(i, j-i);
|
|
|
- ctx->emit_(OP_LOAD_CONST, ctx->add_const(VAR(literal)), line);
|
|
|
+ ctx->emit_(OP_LOAD_CONST, ctx->add_const_string(literal.sv()), line);
|
|
|
count++;
|
|
|
continue; // skip j++
|
|
|
}
|
|
|
@@ -496,7 +497,7 @@ namespace pkpy{
|
|
|
if(flag){
|
|
|
// literal
|
|
|
Str literal = src.substr(i, src.size-i);
|
|
|
- ctx->emit_(OP_LOAD_CONST, ctx->add_const(VAR(literal)), line);
|
|
|
+ ctx->emit_(OP_LOAD_CONST, ctx->add_const_string(literal.sv()), line);
|
|
|
count++;
|
|
|
}
|
|
|
|
|
|
@@ -576,7 +577,7 @@ namespace pkpy{
|
|
|
item.second->emit_(ctx);
|
|
|
}else{
|
|
|
// k=v
|
|
|
- int index = ctx->add_const(py_var(ctx->vm, item.first));
|
|
|
+ int index = ctx->add_const_string(item.first.sv());
|
|
|
ctx->emit_(OP_LOAD_CONST, index, line);
|
|
|
item.second->emit_(ctx);
|
|
|
ctx->emit_(OP_BUILD_TUPLE, 2, line);
|