mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
up
This commit is contained in:
parent
be556ef2ab
commit
1e3e88d832
@ -5,4 +5,6 @@ def fib(n):
|
|||||||
|
|
||||||
assert fib(32) == 2178309
|
assert fib(32) == 2178309
|
||||||
|
|
||||||
|
# from dis import dis
|
||||||
|
# dis(fib)
|
||||||
# 7049155 calls
|
# 7049155 calls
|
33
src/ceval.h
33
src/ceval.h
@ -30,7 +30,6 @@ __NEXT_FRAME:
|
|||||||
Bytecode byte = frame->next_bytecode();
|
Bytecode byte = frame->next_bytecode();
|
||||||
// cache
|
// cache
|
||||||
const CodeObject* co = frame->co;
|
const CodeObject* co = frame->co;
|
||||||
const auto& co_names = co->names;
|
|
||||||
const auto& co_consts = co->consts;
|
const auto& co_consts = co->consts;
|
||||||
const auto& co_blocks = co->blocks;
|
const auto& co_blocks = co->blocks;
|
||||||
|
|
||||||
@ -74,6 +73,7 @@ __NEXT_STEP:;
|
|||||||
TARGET(LOAD_NONE) frame->push(None); DISPATCH();
|
TARGET(LOAD_NONE) frame->push(None); DISPATCH();
|
||||||
TARGET(LOAD_TRUE) frame->push(True); DISPATCH();
|
TARGET(LOAD_TRUE) frame->push(True); DISPATCH();
|
||||||
TARGET(LOAD_FALSE) frame->push(False); DISPATCH();
|
TARGET(LOAD_FALSE) frame->push(False); DISPATCH();
|
||||||
|
TARGET(LOAD_INTEGER) frame->push(VAR(byte.arg)); DISPATCH();
|
||||||
TARGET(LOAD_ELLIPSIS) frame->push(Ellipsis); DISPATCH();
|
TARGET(LOAD_ELLIPSIS) frame->push(Ellipsis); DISPATCH();
|
||||||
TARGET(LOAD_BUILTIN_EVAL) frame->push(builtins->attr(m_eval)); DISPATCH();
|
TARGET(LOAD_BUILTIN_EVAL) frame->push(builtins->attr(m_eval)); DISPATCH();
|
||||||
TARGET(LOAD_FUNCTION) {
|
TARGET(LOAD_FUNCTION) {
|
||||||
@ -96,7 +96,7 @@ __NEXT_STEP:;
|
|||||||
} DISPATCH();
|
} DISPATCH();
|
||||||
TARGET(LOAD_NAME) {
|
TARGET(LOAD_NAME) {
|
||||||
heap._auto_collect();
|
heap._auto_collect();
|
||||||
StrName name = co_names[byte.arg];
|
StrName name(byte.arg);
|
||||||
PyObject* val;
|
PyObject* val;
|
||||||
val = frame->_locals.try_get(name);
|
val = frame->_locals.try_get(name);
|
||||||
if(val != nullptr) { frame->push(val); DISPATCH(); }
|
if(val != nullptr) { frame->push(val); DISPATCH(); }
|
||||||
@ -110,7 +110,7 @@ __NEXT_STEP:;
|
|||||||
} DISPATCH();
|
} DISPATCH();
|
||||||
TARGET(LOAD_NONLOCAL) {
|
TARGET(LOAD_NONLOCAL) {
|
||||||
heap._auto_collect();
|
heap._auto_collect();
|
||||||
StrName name = co_names[byte.arg];
|
StrName name(byte.arg);
|
||||||
PyObject* val;
|
PyObject* val;
|
||||||
val = frame->_closure.try_get(name);
|
val = frame->_closure.try_get(name);
|
||||||
if(val != nullptr) { frame->push(val); DISPATCH(); }
|
if(val != nullptr) { frame->push(val); DISPATCH(); }
|
||||||
@ -122,7 +122,7 @@ __NEXT_STEP:;
|
|||||||
} DISPATCH();
|
} DISPATCH();
|
||||||
TARGET(LOAD_GLOBAL) {
|
TARGET(LOAD_GLOBAL) {
|
||||||
heap._auto_collect();
|
heap._auto_collect();
|
||||||
StrName name = co_names[byte.arg];
|
StrName name(byte.arg);
|
||||||
PyObject* val = frame->f_globals().try_get(name);
|
PyObject* val = frame->f_globals().try_get(name);
|
||||||
if(val != nullptr) { frame->push(val); DISPATCH(); }
|
if(val != nullptr) { frame->push(val); DISPATCH(); }
|
||||||
val = vm->builtins->attr().try_get(name);
|
val = vm->builtins->attr().try_get(name);
|
||||||
@ -131,12 +131,12 @@ __NEXT_STEP:;
|
|||||||
} DISPATCH();
|
} DISPATCH();
|
||||||
TARGET(LOAD_ATTR) {
|
TARGET(LOAD_ATTR) {
|
||||||
PyObject* a = frame->top();
|
PyObject* a = frame->top();
|
||||||
StrName name = co_names[byte.arg];
|
StrName name(byte.arg);
|
||||||
frame->top() = getattr(a, name);
|
frame->top() = getattr(a, name);
|
||||||
} DISPATCH();
|
} DISPATCH();
|
||||||
TARGET(LOAD_METHOD) {
|
TARGET(LOAD_METHOD) {
|
||||||
PyObject* a = frame->top();
|
PyObject* a = frame->top();
|
||||||
StrName name = co_names[byte.arg];
|
StrName name(byte.arg);
|
||||||
PyObject* self;
|
PyObject* self;
|
||||||
frame->top() = get_unbound_method(a, name, &self, true, true);
|
frame->top() = get_unbound_method(a, name, &self, true, true);
|
||||||
frame->push(self);
|
frame->push(self);
|
||||||
@ -151,11 +151,11 @@ __NEXT_STEP:;
|
|||||||
frame->_locals[byte.arg] = frame->popx();
|
frame->_locals[byte.arg] = frame->popx();
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
TARGET(STORE_GLOBAL) {
|
TARGET(STORE_GLOBAL) {
|
||||||
StrName name = co_names[byte.arg];
|
StrName name(byte.arg);
|
||||||
frame->f_globals().set(name, frame->popx());
|
frame->f_globals().set(name, frame->popx());
|
||||||
} DISPATCH();
|
} DISPATCH();
|
||||||
TARGET(STORE_ATTR) {
|
TARGET(STORE_ATTR) {
|
||||||
StrName name = co_names[byte.arg];
|
StrName name(byte.arg);
|
||||||
PyObject* a = frame->top();
|
PyObject* a = frame->top();
|
||||||
PyObject* val = frame->top_1();
|
PyObject* val = frame->top_1();
|
||||||
setattr(a, name, val);
|
setattr(a, name, val);
|
||||||
@ -174,7 +174,7 @@ __NEXT_STEP:;
|
|||||||
frame->_locals[byte.arg] = nullptr;
|
frame->_locals[byte.arg] = nullptr;
|
||||||
} DISPATCH();
|
} DISPATCH();
|
||||||
TARGET(DELETE_GLOBAL) {
|
TARGET(DELETE_GLOBAL) {
|
||||||
StrName name = co_names[byte.arg];
|
StrName name(byte.arg);
|
||||||
if(frame->f_globals().contains(name)){
|
if(frame->f_globals().contains(name)){
|
||||||
frame->f_globals().erase(name);
|
frame->f_globals().erase(name);
|
||||||
}else{
|
}else{
|
||||||
@ -183,7 +183,7 @@ __NEXT_STEP:;
|
|||||||
} DISPATCH();
|
} DISPATCH();
|
||||||
TARGET(DELETE_ATTR) {
|
TARGET(DELETE_ATTR) {
|
||||||
PyObject* a = frame->popx();
|
PyObject* a = frame->popx();
|
||||||
StrName name = co_names[byte.arg];
|
StrName name(byte.arg);
|
||||||
if(!a->is_attr_valid()) TypeError("cannot delete attribute");
|
if(!a->is_attr_valid()) TypeError("cannot delete attribute");
|
||||||
if(!a->attr().contains(name)) AttributeError(a, name);
|
if(!a->attr().contains(name)) AttributeError(a, name);
|
||||||
a->attr().erase(name);
|
a->attr().erase(name);
|
||||||
@ -335,7 +335,7 @@ __NEXT_STEP:;
|
|||||||
frame->jump_abs_break(target);
|
frame->jump_abs_break(target);
|
||||||
} DISPATCH();
|
} DISPATCH();
|
||||||
TARGET(GOTO) {
|
TARGET(GOTO) {
|
||||||
StrName name = co_names[byte.arg];
|
StrName name(byte.arg);
|
||||||
int index = co->labels->try_get(name);
|
int index = co->labels->try_get(name);
|
||||||
if(index < 0) _error("KeyError", fmt("label ", name.escape(), " not found"));
|
if(index < 0) _error("KeyError", fmt("label ", name.escape(), " not found"));
|
||||||
frame->jump_abs_break(index);
|
frame->jump_abs_break(index);
|
||||||
@ -437,7 +437,7 @@ __NEXT_STEP:;
|
|||||||
} DISPATCH();
|
} DISPATCH();
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
TARGET(IMPORT_NAME) {
|
TARGET(IMPORT_NAME) {
|
||||||
StrName name = co_names[byte.arg];
|
StrName name(byte.arg);
|
||||||
PyObject* ext_mod = _modules.try_get(name);
|
PyObject* ext_mod = _modules.try_get(name);
|
||||||
if(ext_mod == nullptr){
|
if(ext_mod == nullptr){
|
||||||
Str source;
|
Str source;
|
||||||
@ -494,7 +494,7 @@ __NEXT_STEP:;
|
|||||||
}; DISPATCH();
|
}; DISPATCH();
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
TARGET(BEGIN_CLASS) {
|
TARGET(BEGIN_CLASS) {
|
||||||
StrName name = co_names[byte.arg];
|
StrName name(byte.arg);
|
||||||
PyObject* super_cls = frame->popx();
|
PyObject* super_cls = frame->popx();
|
||||||
if(super_cls == None) super_cls = _t(tp_object);
|
if(super_cls == None) super_cls = _t(tp_object);
|
||||||
check_type(super_cls, tp_type);
|
check_type(super_cls, tp_type);
|
||||||
@ -506,7 +506,7 @@ __NEXT_STEP:;
|
|||||||
cls->attr()._try_perfect_rehash();
|
cls->attr()._try_perfect_rehash();
|
||||||
}; DISPATCH();
|
}; DISPATCH();
|
||||||
TARGET(STORE_CLASS_ATTR) {
|
TARGET(STORE_CLASS_ATTR) {
|
||||||
StrName name = co_names[byte.arg];
|
StrName name(byte.arg);
|
||||||
PyObject* obj = frame->popx();
|
PyObject* obj = frame->popx();
|
||||||
PyObject* cls = frame->top();
|
PyObject* cls = frame->top();
|
||||||
cls->attr().set(name, obj);
|
cls->attr().set(name, obj);
|
||||||
@ -531,14 +531,13 @@ __NEXT_STEP:;
|
|||||||
} DISPATCH();
|
} DISPATCH();
|
||||||
TARGET(EXCEPTION_MATCH) {
|
TARGET(EXCEPTION_MATCH) {
|
||||||
const auto& e = CAST(Exception&, frame->top());
|
const auto& e = CAST(Exception&, frame->top());
|
||||||
StrName name = co_names[byte.arg];
|
StrName name(byte.arg);
|
||||||
frame->push(VAR(e.match_type(name)));
|
frame->push(VAR(e.match_type(name)));
|
||||||
} DISPATCH();
|
} DISPATCH();
|
||||||
TARGET(RAISE) {
|
TARGET(RAISE) {
|
||||||
PyObject* obj = frame->popx();
|
PyObject* obj = frame->popx();
|
||||||
Str msg = obj == None ? "" : CAST(Str, asStr(obj));
|
Str msg = obj == None ? "" : CAST(Str, asStr(obj));
|
||||||
StrName type = co_names[byte.arg];
|
_error(StrName(byte.arg), msg);
|
||||||
_error(type, msg);
|
|
||||||
} DISPATCH();
|
} DISPATCH();
|
||||||
TARGET(RE_RAISE) _raise(); DISPATCH();
|
TARGET(RE_RAISE) _raise(); DISPATCH();
|
||||||
#if !PK_ENABLE_COMPUTED_GOTO
|
#if !PK_ENABLE_COMPUTED_GOTO
|
||||||
|
@ -61,7 +61,6 @@ struct CodeObject {
|
|||||||
std::vector<Bytecode> codes;
|
std::vector<Bytecode> codes;
|
||||||
std::vector<int> lines; // line number for each bytecode
|
std::vector<int> lines; // line number for each bytecode
|
||||||
List consts;
|
List consts;
|
||||||
std::vector<StrName> names; // other names
|
|
||||||
std::vector<StrName> varnames; // local variables
|
std::vector<StrName> varnames; // local variables
|
||||||
NameDictInt_ varnames_inv;
|
NameDictInt_ varnames_inv;
|
||||||
std::set<Str> global_names;
|
std::set<Str> global_names;
|
||||||
|
@ -524,8 +524,7 @@ __SUBSCR_END:
|
|||||||
if(name_scope() != NAME_GLOBAL) SyntaxError("import statement should be used in global scope");
|
if(name_scope() != NAME_GLOBAL) SyntaxError("import statement should be used in global scope");
|
||||||
consume(TK("@id"));
|
consume(TK("@id"));
|
||||||
Str name = prev().str();
|
Str name = prev().str();
|
||||||
int index = ctx()->add_name(name);
|
ctx()->emit(OP_IMPORT_NAME, StrName(name).index, prev().line);
|
||||||
ctx()->emit(OP_IMPORT_NAME, index, prev().line);
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,7 +536,7 @@ __SUBSCR_END:
|
|||||||
consume(TK("@id"));
|
consume(TK("@id"));
|
||||||
name = prev().str();
|
name = prev().str();
|
||||||
}
|
}
|
||||||
ctx()->emit(OP_STORE_GLOBAL, ctx()->add_name(name), prev().line);
|
ctx()->emit(OP_STORE_GLOBAL, StrName(name).index, prev().line);
|
||||||
} while (match(TK(",")));
|
} while (match(TK(",")));
|
||||||
consume_end_stmt();
|
consume_end_stmt();
|
||||||
}
|
}
|
||||||
@ -555,13 +554,12 @@ __SUBSCR_END:
|
|||||||
ctx()->emit(OP_DUP_TOP, BC_NOARG, BC_KEEPLINE);
|
ctx()->emit(OP_DUP_TOP, BC_NOARG, BC_KEEPLINE);
|
||||||
consume(TK("@id"));
|
consume(TK("@id"));
|
||||||
Str name = prev().str();
|
Str name = prev().str();
|
||||||
int index = ctx()->add_name(name);
|
ctx()->emit(OP_LOAD_ATTR, StrName(name).index, prev().line);
|
||||||
ctx()->emit(OP_LOAD_ATTR, index, prev().line);
|
|
||||||
if (match(TK("as"))) {
|
if (match(TK("as"))) {
|
||||||
consume(TK("@id"));
|
consume(TK("@id"));
|
||||||
name = prev().str();
|
name = prev().str();
|
||||||
}
|
}
|
||||||
ctx()->emit(OP_STORE_GLOBAL, ctx()->add_name(name), prev().line);
|
ctx()->emit(OP_STORE_GLOBAL, StrName(name).index, prev().line);
|
||||||
} while (match(TK(",")));
|
} while (match(TK(",")));
|
||||||
ctx()->emit(OP_POP_TOP, BC_NOARG, BC_KEEPLINE);
|
ctx()->emit(OP_POP_TOP, BC_NOARG, BC_KEEPLINE);
|
||||||
consume_end_stmt();
|
consume_end_stmt();
|
||||||
@ -638,8 +636,7 @@ __SUBSCR_END:
|
|||||||
do {
|
do {
|
||||||
consume(TK("except"));
|
consume(TK("except"));
|
||||||
if(match(TK("@id"))){
|
if(match(TK("@id"))){
|
||||||
int namei = ctx()->add_name(prev().str());
|
ctx()->emit(OP_EXCEPTION_MATCH, StrName(prev().str()).index, prev().line);
|
||||||
ctx()->emit(OP_EXCEPTION_MATCH, namei, prev().line);
|
|
||||||
}else{
|
}else{
|
||||||
ctx()->emit(OP_LOAD_TRUE, BC_NOARG, BC_KEEPLINE);
|
ctx()->emit(OP_LOAD_TRUE, BC_NOARG, BC_KEEPLINE);
|
||||||
}
|
}
|
||||||
@ -760,7 +757,7 @@ __SUBSCR_END:
|
|||||||
break;
|
break;
|
||||||
case TK("raise"): {
|
case TK("raise"): {
|
||||||
consume(TK("@id"));
|
consume(TK("@id"));
|
||||||
int dummy_t = ctx()->add_name(prev().str());
|
int dummy_t = StrName(prev().str()).index;
|
||||||
if(match(TK("(")) && !match(TK(")"))){
|
if(match(TK("(")) && !match(TK(")"))){
|
||||||
EXPR(false); consume(TK(")"));
|
EXPR(false); consume(TK(")"));
|
||||||
}else{
|
}else{
|
||||||
@ -782,7 +779,6 @@ __SUBSCR_END:
|
|||||||
ctx()->emit(OP_POP_TOP, BC_NOARG, prev().line);
|
ctx()->emit(OP_POP_TOP, BC_NOARG, prev().line);
|
||||||
consume(TK("as"));
|
consume(TK("as"));
|
||||||
consume(TK("@id"));
|
consume(TK("@id"));
|
||||||
// int index = ctx()->add_name(prev().str());
|
|
||||||
// emit(OP_STORE_NAME, index);
|
// emit(OP_STORE_NAME, index);
|
||||||
// emit(OP_LOAD_NAME_REF, index);
|
// emit(OP_LOAD_NAME_REF, index);
|
||||||
// emit(OP_WITH_ENTER);
|
// emit(OP_WITH_ENTER);
|
||||||
@ -802,7 +798,7 @@ __SUBSCR_END:
|
|||||||
case TK("goto"):
|
case TK("goto"):
|
||||||
if(mode()!=EXEC_MODE) SyntaxError("'goto' is only available in EXEC_MODE");
|
if(mode()!=EXEC_MODE) SyntaxError("'goto' is only available in EXEC_MODE");
|
||||||
consume(TK(".")); consume(TK("@id"));
|
consume(TK(".")); consume(TK("@id"));
|
||||||
ctx()->emit(OP_GOTO, ctx()->add_name(prev().str()), prev().line);
|
ctx()->emit(OP_GOTO, StrName(prev().str()).index, prev().line);
|
||||||
consume_end_stmt();
|
consume_end_stmt();
|
||||||
break;
|
break;
|
||||||
/*************************************************/
|
/*************************************************/
|
||||||
@ -826,10 +822,10 @@ __SUBSCR_END:
|
|||||||
|
|
||||||
void compile_class(){
|
void compile_class(){
|
||||||
consume(TK("@id"));
|
consume(TK("@id"));
|
||||||
int namei = ctx()->add_name(prev().str());
|
int namei = StrName(prev().str()).index;
|
||||||
int super_namei = -1;
|
int super_namei = -1;
|
||||||
if(match(TK("(")) && match(TK("@id"))){
|
if(match(TK("(")) && match(TK("@id"))){
|
||||||
super_namei = ctx()->add_name(prev().str());
|
super_namei = StrName(prev().str()).index;
|
||||||
consume(TK(")"));
|
consume(TK(")"));
|
||||||
}
|
}
|
||||||
if(super_namei == -1) ctx()->emit(OP_LOAD_NONE, BC_NOARG, prev().line);
|
if(super_namei == -1) ctx()->emit(OP_LOAD_NONE, BC_NOARG, prev().line);
|
||||||
@ -932,26 +928,41 @@ __SUBSCR_END:
|
|||||||
auto e = make_expr<NameExpr>(decl_name, name_scope());
|
auto e = make_expr<NameExpr>(decl_name, name_scope());
|
||||||
e->emit_store(ctx());
|
e->emit_store(ctx());
|
||||||
} else {
|
} else {
|
||||||
ctx()->emit(OP_LOAD_GLOBAL, ctx()->add_name(obj_name), prev().line);
|
ctx()->emit(OP_LOAD_GLOBAL, StrName(obj_name).index, prev().line);
|
||||||
int index = ctx()->add_name(decl_name);
|
int index = StrName(decl_name).index;
|
||||||
ctx()->emit(OP_STORE_ATTR, index, prev().line);
|
ctx()->emit(OP_STORE_ATTR, index, prev().line);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
int index = ctx()->add_name(decl_name);
|
int index = StrName(decl_name).index;
|
||||||
ctx()->emit(OP_STORE_CLASS_ATTR, index, prev().line);
|
ctx()->emit(OP_STORE_CLASS_ATTR, index, prev().line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject* to_object(const TokenValue& value){
|
||||||
|
PyObject* obj = nullptr;
|
||||||
|
if(std::holds_alternative<i64>(value)){
|
||||||
|
obj = VAR(std::get<i64>(value));
|
||||||
|
}
|
||||||
|
if(std::holds_alternative<f64>(value)){
|
||||||
|
obj = VAR(std::get<f64>(value));
|
||||||
|
}
|
||||||
|
if(std::holds_alternative<Str>(value)){
|
||||||
|
obj = VAR(std::get<Str>(value));
|
||||||
|
}
|
||||||
|
if(obj == nullptr) FATAL_ERROR();
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
PyObject* read_literal(){
|
PyObject* read_literal(){
|
||||||
advance();
|
advance();
|
||||||
switch(prev().type){
|
switch(prev().type){
|
||||||
case TK("-"): {
|
case TK("-"): {
|
||||||
consume(TK("@num"));
|
consume(TK("@num"));
|
||||||
PyObject* val = LiteralExpr(prev().value).to_object(ctx());
|
PyObject* val = to_object(prev().value);
|
||||||
return vm->num_negated(val);
|
return vm->num_negated(val);
|
||||||
}
|
}
|
||||||
case TK("@num"): return LiteralExpr(prev().value).to_object(ctx());
|
case TK("@num"): return to_object(prev().value);
|
||||||
case TK("@str"): return LiteralExpr(prev().value).to_object(ctx());
|
case TK("@str"): return to_object(prev().value);
|
||||||
case TK("True"): return VAR(true);
|
case TK("True"): return VAR(true);
|
||||||
case TK("False"): return VAR(false);
|
case TK("False"): return VAR(false);
|
||||||
case TK("None"): return vm->None;
|
case TK("None"): return vm->None;
|
||||||
|
54
src/expr.h
54
src/expr.h
@ -99,14 +99,6 @@ struct CodeEmitContext{
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int add_name(StrName name){
|
|
||||||
for(int i=0; i<co->names.size(); i++){
|
|
||||||
if(co->names[i] == name) return i;
|
|
||||||
}
|
|
||||||
co->names.push_back(name);
|
|
||||||
return co->names.size() - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int add_varname(StrName name){
|
int add_varname(StrName name){
|
||||||
int index = co->varnames_inv->try_get(name);
|
int index = co->varnames_inv->try_get(name);
|
||||||
if(index >= 0) return index;
|
if(index >= 0) return index;
|
||||||
@ -144,7 +136,7 @@ struct NameExpr: Expr{
|
|||||||
ctx->emit(OP_LOAD_FAST, index, line);
|
ctx->emit(OP_LOAD_FAST, index, line);
|
||||||
}else{
|
}else{
|
||||||
Opcode op = ctx->level <= 1 ? OP_LOAD_GLOBAL : OP_LOAD_NONLOCAL;
|
Opcode op = ctx->level <= 1 ? OP_LOAD_GLOBAL : OP_LOAD_NONLOCAL;
|
||||||
ctx->emit(op, ctx->add_name(name), line);
|
ctx->emit(op, StrName(name).index, line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +146,7 @@ struct NameExpr: Expr{
|
|||||||
ctx->emit(OP_DELETE_FAST, ctx->add_varname(name), line);
|
ctx->emit(OP_DELETE_FAST, ctx->add_varname(name), line);
|
||||||
break;
|
break;
|
||||||
case NAME_GLOBAL:
|
case NAME_GLOBAL:
|
||||||
ctx->emit(OP_DELETE_GLOBAL, ctx->add_name(name), line);
|
ctx->emit(OP_DELETE_GLOBAL, StrName(name).index, line);
|
||||||
break;
|
break;
|
||||||
default: FATAL_ERROR(); break;
|
default: FATAL_ERROR(); break;
|
||||||
}
|
}
|
||||||
@ -163,7 +155,7 @@ struct NameExpr: Expr{
|
|||||||
|
|
||||||
bool emit_store(CodeEmitContext* ctx) override {
|
bool emit_store(CodeEmitContext* ctx) override {
|
||||||
if(ctx->is_compiling_class){
|
if(ctx->is_compiling_class){
|
||||||
int index = ctx->add_name(name);
|
int index = StrName(name).index;
|
||||||
ctx->emit(OP_STORE_CLASS_ATTR, index, line);
|
ctx->emit(OP_STORE_CLASS_ATTR, index, line);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -172,7 +164,7 @@ struct NameExpr: Expr{
|
|||||||
ctx->emit(OP_STORE_FAST, ctx->add_varname(name), line);
|
ctx->emit(OP_STORE_FAST, ctx->add_varname(name), line);
|
||||||
break;
|
break;
|
||||||
case NAME_GLOBAL:
|
case NAME_GLOBAL:
|
||||||
ctx->emit(OP_STORE_GLOBAL, ctx->add_name(name), line);
|
ctx->emit(OP_STORE_GLOBAL, StrName(name).index, line);
|
||||||
break;
|
break;
|
||||||
default: FATAL_ERROR(); break;
|
default: FATAL_ERROR(); break;
|
||||||
}
|
}
|
||||||
@ -276,11 +268,16 @@ struct LiteralExpr: Expr{
|
|||||||
FATAL_ERROR();
|
FATAL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* to_object(CodeEmitContext* ctx){
|
void emit(CodeEmitContext* ctx) override {
|
||||||
VM* vm = ctx->vm;
|
VM* vm = ctx->vm;
|
||||||
PyObject* obj = nullptr;
|
PyObject* obj = nullptr;
|
||||||
if(std::holds_alternative<i64>(value)){
|
if(std::holds_alternative<i64>(value)){
|
||||||
obj = VAR(std::get<i64>(value));
|
i64 _val = std::get<i64>(value);
|
||||||
|
if(_val >= INT16_MIN && _val <= INT16_MAX){
|
||||||
|
ctx->emit(OP_LOAD_INTEGER, (int)_val, line);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
obj = VAR(_val);
|
||||||
}
|
}
|
||||||
if(std::holds_alternative<f64>(value)){
|
if(std::holds_alternative<f64>(value)){
|
||||||
obj = VAR(std::get<f64>(value));
|
obj = VAR(std::get<f64>(value));
|
||||||
@ -288,14 +285,8 @@ struct LiteralExpr: Expr{
|
|||||||
if(std::holds_alternative<Str>(value)){
|
if(std::holds_alternative<Str>(value)){
|
||||||
obj = VAR(std::get<Str>(value));
|
obj = VAR(std::get<Str>(value));
|
||||||
}
|
}
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
void emit(CodeEmitContext* ctx) override {
|
|
||||||
PyObject* obj = to_object(ctx);
|
|
||||||
if(obj == nullptr) FATAL_ERROR();
|
if(obj == nullptr) FATAL_ERROR();
|
||||||
int index = ctx->add_const(obj);
|
ctx->emit(OP_LOAD_CONST, ctx->add_const(obj), line);
|
||||||
ctx->emit(OP_LOAD_CONST, index, line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_literal() const override { return true; }
|
bool is_literal() const override { return true; }
|
||||||
@ -312,14 +303,17 @@ struct NegatedExpr: Expr{
|
|||||||
// if child is a int of float, do constant folding
|
// if child is a int of float, do constant folding
|
||||||
if(child->is_literal()){
|
if(child->is_literal()){
|
||||||
LiteralExpr* lit = static_cast<LiteralExpr*>(child.get());
|
LiteralExpr* lit = static_cast<LiteralExpr*>(child.get());
|
||||||
PyObject* obj = nullptr;
|
|
||||||
if(std::holds_alternative<i64>(lit->value)){
|
if(std::holds_alternative<i64>(lit->value)){
|
||||||
obj = VAR(-std::get<i64>(lit->value));
|
i64 _val = -std::get<i64>(lit->value);
|
||||||
|
if(_val >= INT16_MIN && _val <= INT16_MAX){
|
||||||
|
ctx->emit(OP_LOAD_INTEGER, (int)_val, line);
|
||||||
|
}else{
|
||||||
|
ctx->emit(OP_LOAD_CONST, ctx->add_const(VAR(_val)), line);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if(std::holds_alternative<f64>(lit->value)){
|
if(std::holds_alternative<f64>(lit->value)){
|
||||||
obj = VAR(-std::get<f64>(lit->value));
|
PyObject* obj = VAR(-std::get<f64>(lit->value));
|
||||||
}
|
|
||||||
if(obj != nullptr){
|
|
||||||
ctx->emit(OP_LOAD_CONST, ctx->add_const(obj), line);
|
ctx->emit(OP_LOAD_CONST, ctx->add_const(obj), line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -585,27 +579,27 @@ struct AttribExpr: Expr{
|
|||||||
|
|
||||||
void emit(CodeEmitContext* ctx) override{
|
void emit(CodeEmitContext* ctx) override{
|
||||||
a->emit(ctx);
|
a->emit(ctx);
|
||||||
int index = ctx->add_name(b);
|
int index = StrName(b).index;
|
||||||
ctx->emit(OP_LOAD_ATTR, index, line);
|
ctx->emit(OP_LOAD_ATTR, index, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit_del(CodeEmitContext* ctx) override {
|
bool emit_del(CodeEmitContext* ctx) override {
|
||||||
a->emit(ctx);
|
a->emit(ctx);
|
||||||
int index = ctx->add_name(b);
|
int index = StrName(b).index;
|
||||||
ctx->emit(OP_DELETE_ATTR, index, line);
|
ctx->emit(OP_DELETE_ATTR, index, line);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit_store(CodeEmitContext* ctx) override {
|
bool emit_store(CodeEmitContext* ctx) override {
|
||||||
a->emit(ctx);
|
a->emit(ctx);
|
||||||
int index = ctx->add_name(b);
|
int index = StrName(b).index;
|
||||||
ctx->emit(OP_STORE_ATTR, index, line);
|
ctx->emit(OP_STORE_ATTR, index, line);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void emit_method(CodeEmitContext* ctx) {
|
void emit_method(CodeEmitContext* ctx) {
|
||||||
a->emit(ctx);
|
a->emit(ctx);
|
||||||
int index = ctx->add_name(b);
|
int index = StrName(b).index;
|
||||||
ctx->emit(OP_LOAD_METHOD, index, line);
|
ctx->emit(OP_LOAD_METHOD, index, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ OPCODE(LOAD_CONST)
|
|||||||
OPCODE(LOAD_NONE)
|
OPCODE(LOAD_NONE)
|
||||||
OPCODE(LOAD_TRUE)
|
OPCODE(LOAD_TRUE)
|
||||||
OPCODE(LOAD_FALSE)
|
OPCODE(LOAD_FALSE)
|
||||||
|
OPCODE(LOAD_INTEGER)
|
||||||
OPCODE(LOAD_ELLIPSIS)
|
OPCODE(LOAD_ELLIPSIS)
|
||||||
OPCODE(LOAD_BUILTIN_EVAL)
|
OPCODE(LOAD_BUILTIN_EVAL)
|
||||||
OPCODE(LOAD_FUNCTION)
|
OPCODE(LOAD_FUNCTION)
|
||||||
|
16
src/vm.h
16
src/vm.h
@ -597,7 +597,7 @@ inline Str VM::disassemble(CodeObject_ co){
|
|||||||
case OP_LOAD_ATTR: case OP_LOAD_METHOD: case OP_STORE_ATTR: case OP_DELETE_ATTR:
|
case OP_LOAD_ATTR: case OP_LOAD_METHOD: case OP_STORE_ATTR: case OP_DELETE_ATTR:
|
||||||
case OP_IMPORT_NAME: case OP_BEGIN_CLASS:
|
case OP_IMPORT_NAME: case OP_BEGIN_CLASS:
|
||||||
case OP_DELETE_GLOBAL:
|
case OP_DELETE_GLOBAL:
|
||||||
argStr += fmt(" (", co->names[byte.arg].sv(), ")");
|
argStr += fmt(" (", StrName(byte.arg).sv(), ")");
|
||||||
break;
|
break;
|
||||||
case OP_LOAD_FAST: case OP_STORE_FAST: case OP_DELETE_FAST:
|
case OP_LOAD_FAST: case OP_STORE_FAST: case OP_DELETE_FAST:
|
||||||
argStr += fmt(" (", co->varnames[byte.arg].sv(), ")");
|
argStr += fmt(" (", co->varnames[byte.arg].sv(), ")");
|
||||||
@ -614,23 +614,11 @@ inline Str VM::disassemble(CodeObject_ co){
|
|||||||
if(i != co->codes.size() - 1) ss << '\n';
|
if(i != co->codes.size() - 1) ss << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
// std::stringstream consts;
|
|
||||||
// consts << "co_consts: ";
|
|
||||||
// consts << CAST(Str&, asRepr(VAR(co->consts)));
|
|
||||||
|
|
||||||
// std::stringstream names;
|
|
||||||
// names << "co_names: ";
|
|
||||||
// List list;
|
|
||||||
// for(int i=0; i<co->names.size(); i++){
|
|
||||||
// list.push_back(VAR(co->names[i].sv()));
|
|
||||||
// }
|
|
||||||
// names << CAST(Str, asRepr(VAR(list)));
|
|
||||||
// ss << '\n' << consts.str() << '\n' << names.str();
|
|
||||||
|
|
||||||
for(auto& decl: co->func_decls){
|
for(auto& decl: co->func_decls){
|
||||||
ss << "\n\n" << "Disassembly of " << decl->code->name << ":\n";
|
ss << "\n\n" << "Disassembly of " << decl->code->name << ":\n";
|
||||||
ss << disassemble(decl->code);
|
ss << disassemble(decl->code);
|
||||||
}
|
}
|
||||||
|
ss << "\n";
|
||||||
return Str(ss.str());
|
return Str(ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user