diff --git a/src/ceval.h b/src/ceval.h index e72c9c09..9a45f1b3 100644 --- a/src/ceval.h +++ b/src/ceval.h @@ -26,49 +26,86 @@ inline PyObject* VM::run_frame(Frame* frame){ Function& f = CAST(Function&, frame->top()); // reference f._closure = frame->_locals; } continue; - case OP_LOAD_NAME_REF: { - frame->push(PyRef(NameRef(frame->co->names[byte.arg]))); - } continue; - case OP_LOAD_NAME: { - frame->push(NameRef(frame->co->names[byte.arg]).get(this, frame)); - } continue; - case OP_STORE_NAME: { - auto& p = frame->co->names[byte.arg]; - NameRef(p).set(this, frame, frame->pop()); - } continue; - case OP_BUILD_ATTR_REF: case OP_BUILD_ATTR: { - auto& attr = frame->co->names[byte.arg]; - PyObject* obj = frame->pop_value(this); - AttrRef ref = AttrRef(obj, NameRef(attr)); - if(byte.op == OP_BUILD_ATTR) frame->push(ref.get(this, frame)); - else frame->push(PyRef(ref)); - } continue; - case OP_BUILD_INDEX: { - PyObject* index = frame->pop_value(this); - auto ref = IndexRef(frame->pop_value(this), index); - if(byte.arg > 0) frame->push(ref.get(this, frame)); - else frame->push(PyRef(ref)); - } continue; - 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)); - } continue; case OP_ROT_TWO: ::std::swap(frame->top(), frame->top_1()); continue; - case OP_STORE_REF: { - PyRef_AS_C(frame->top_1())->set(this, frame, frame->top_value(this)); - frame->_pop(); frame->_pop(); - } continue; - case OP_DELETE_REF: - PyRef_AS_C(frame->top())->del(this, frame); - frame->_pop(); - continue; case OP_BUILD_TUPLE: { Args items = frame->pop_n_values_reversed(this, byte.arg); frame->push(VAR(std::move(items))); } continue; + /*****************************************/ + case OP_LOAD_NAME: { + // TODO: use name resolution linked list to optimize this + StrName name = frame->co->names[byte.arg]; + PyObject* val; + val = frame->f_locals().try_get(name); + if(val != nullptr) { frame->push(val); continue; } + val = frame->f_closure_try_get(name); + if(val != nullptr) { frame->push(val); continue; } + val = frame->f_globals().try_get(name); + if(val != nullptr) { frame->push(val); continue; } + val = vm->builtins->attr().try_get(name); + if(val != nullptr) { frame->push(val); continue; } + vm->NameError(name); + } continue; + case OP_LOAD_ATTR: { + PyObject* a = frame->top(); + StrName name = frame->co->names[byte.arg]; + frame->top() = getattr(a, name); + } continue; + case OP_LOAD_SUBSCR: { + PyObject* b = frame->popx(); + PyObject* a = frame->top(); + frame->top() = fast_call(__getitem__, Args{a, b}); + } continue; + case OP_STORE_LOCAL: { + StrName name = frame->co->names[byte.arg]; + frame->f_locals().set(name, frame->popx()); + } continue; + case OP_STORE_GLOBAL: { + StrName name = frame->co->names[byte.arg]; + frame->f_globals().set(name, frame->popx()); + } continue; + case OP_STORE_ATTR: { + StrName name = frame->co->names[byte.arg]; + PyObject* a = frame->popx(); + PyObject* val = frame->popx(); + setattr(a, name, val); + } continue; + case OP_STORE_SUBSCR: { + Args args(3); + args[1] = frame->popx(); // b + args[0] = frame->popx(); // a + args[2] = frame->popx(); // val + fast_call(__setitem__, std::move(args)); + } continue; + case OP_DELETE_LOCAL: { + StrName name = frame->co->names[byte.arg]; + if(frame->f_locals().contains(name)){ + frame->f_locals().erase(name); + }else{ + NameError(name); + } + } continue; + case OP_DELETE_GLOBAL: { + StrName name = frame->co->names[byte.arg]; + if(frame->f_globals().contains(name)){ + frame->f_globals().erase(name); + }else{ + NameError(name); + } + } continue; + case OP_DELETE_ATTR: { + PyObject* a = frame->popx(); + StrName name = frame->co->names[byte.arg]; + if(!a->is_attr_valid()) TypeError("cannot delete attribute"); + if(!a->attr().contains(name)) AttributeError(a, name); + a->attr().erase(name); + } continue; + case OP_DELETE_SUBSCR: { + PyObject* b = frame->popx(); + PyObject* a = frame->popx(); + fast_call(__delitem__, Args{a, b}); + } continue; + /*****************************************/ case OP_BUILD_TUPLE_REF: { Args items = frame->pop_n_reversed(byte.arg); frame->push(PyRef(TupleRef(std::move(items)))); diff --git a/src/codeobject.h b/src/codeobject.h index 3ac01caa..b238bc7a 100644 --- a/src/codeobject.h +++ b/src/codeobject.h @@ -25,7 +25,7 @@ inline const char* OP_NAMES[] = { }; struct Bytecode{ - uint8_t op; + uint16_t op; uint16_t block; int arg; int line; @@ -61,7 +61,7 @@ struct CodeObject { std::vector codes; List consts; - std::vector> names; + std::vector names; std::set global_names; std::vector blocks = { CodeBlock{NO_BLOCK, -1} }; std::map labels; diff --git a/src/compiler.h b/src/compiler.h index 10eb8886..a4647e49 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -173,7 +173,7 @@ private: } template - std::unique_ptr expr_prev_line(Args&&... args) { + std::unique_ptr make_expr(Args&&... args) { std::unique_ptr expr = std::make_unique(std::forward(args)...); expr->line = prev().line; return expr; @@ -183,17 +183,17 @@ private: // PASS void exprLiteral(){ - ctx()->s_expr.push(expr_prev_line(prev().value)); + ctx()->s_expr.push(make_expr(prev().value)); } // PASS void exprFString(){ - ctx()->s_expr.push(expr_prev_line(std::get(prev().value))); + ctx()->s_expr.push(make_expr(std::get(prev().value))); } // PASS void exprLambda(){ - auto e = expr_prev_line(); + auto e = make_expr(); e->func.name = ""; e->scope = name_scope(); if(!match(TK(":"))){ @@ -260,7 +260,7 @@ private: // PASS void exprTuple(){ - auto e = expr_prev_line(); + auto e = make_expr(); do { EXPR(); // NOTE: "1," will fail, "1,2" will be ok e->items.push_back(ctx()->s_expr.popx()); @@ -270,7 +270,7 @@ private: // PASS void exprOr(){ - auto e = expr_prev_line(); + auto e = make_expr(); e->lhs = ctx()->s_expr.popx(); parse_expression(PREC_LOGICAL_OR + 1); e->rhs = ctx()->s_expr.popx(); @@ -279,7 +279,7 @@ private: // PASS void exprAnd(){ - auto e = expr_prev_line(); + auto e = make_expr(); e->lhs = ctx()->s_expr.popx(); parse_expression(PREC_LOGICAL_AND + 1); e->rhs = ctx()->s_expr.popx(); @@ -288,7 +288,7 @@ private: // PASS void exprTernary(){ - auto e = expr_prev_line(); + auto e = make_expr(); e->cond = ctx()->s_expr.popx(); EXPR(); // if true e->true_expr = ctx()->s_expr.popx(); @@ -300,7 +300,7 @@ private: // PASS void exprBinaryOp(){ - auto e = expr_prev_line(); + auto e = make_expr(); e->op = prev().type; e->lhs = ctx()->s_expr.popx(); parse_expression(rules[e->op].precedence + 1); @@ -311,7 +311,7 @@ private: // PASS void exprNot() { parse_expression(PREC_LOGICAL_NOT + 1); - ctx()->s_expr.push(expr_prev_line(ctx()->s_expr.popx())); + ctx()->s_expr.push(make_expr(ctx()->s_expr.popx())); } // PASS @@ -320,10 +320,10 @@ private: parse_expression(PREC_UNARY + 1); switch(op){ case TK("-"): - ctx()->s_expr.push(expr_prev_line(ctx()->s_expr.popx())); + ctx()->s_expr.push(make_expr(ctx()->s_expr.popx())); break; case TK("*"): - ctx()->s_expr.push(expr_prev_line(ctx()->s_expr.popx())); + ctx()->s_expr.push(make_expr(ctx()->s_expr.popx())); break; default: UNREACHABLE(); } @@ -375,7 +375,7 @@ private: match_newlines(mode()==REPL_MODE); } while (match(TK(","))); consume(TK("]")); - auto e = expr_prev_line(std::move(items)); + auto e = make_expr(std::move(items)); e->line = line; // override line ctx()->s_expr.push(std::move(e)); } @@ -392,7 +392,7 @@ private: if(parsing_dict){ consume(TK(":")); EXPR(); - auto dict_item = expr_prev_line(); + auto dict_item = make_expr(); dict_item->key = ctx()->s_expr.popx(); dict_item->value = ctx()->s_expr.popx(); items.push_back(std::move(dict_item)); @@ -410,17 +410,17 @@ private: } while (match(TK(","))); consume(TK("}")); if(items.size()==0 || parsing_dict){ - auto e = expr_prev_line(std::move(items)); + auto e = make_expr(std::move(items)); ctx()->s_expr.push(std::move(e)); }else{ - auto e = expr_prev_line(std::move(items)); + auto e = make_expr(std::move(items)); ctx()->s_expr.push(std::move(e)); } } // PASS void exprCall() { - auto e = expr_prev_line(); + auto e = make_expr(); e->callable = ctx()->s_expr.popx(); do { match_newlines(mode()==REPL_MODE); @@ -434,38 +434,32 @@ private: } else{ if(!e->kwargs.empty()) SyntaxError("positional argument follows keyword argument"); EXPR(); - // if(co()->codes.back().op == OP_UNARY_STAR) need_unpack = true; e->args.push_back(ctx()->s_expr.popx()); } match_newlines(mode()==REPL_MODE); } while (match(TK(","))); consume(TK(")")); + if(e->args.size() > 32767) SyntaxError("too many positional arguments"); + if(e->kwargs.size() > 32767) SyntaxError("too many keyword arguments"); ctx()->s_expr.push(std::move(e)); - // if(ARGC > 32767) SyntaxError("too many positional arguments"); - // if(KWARGC > 32767) SyntaxError("too many keyword arguments"); - // if(KWARGC > 0){ - // emit(need_unpack ? OP_CALL_KWARGS_UNPACK : OP_CALL_KWARGS, (KWARGC << 16) | ARGC); - // }else{ - // emit(need_unpack ? OP_CALL_UNPACK : OP_CALL, ARGC); - // } } // PASS void exprName(){ - ctx()->s_expr.push(expr_prev_line(prev().str(), name_scope())); + ctx()->s_expr.push(make_expr(prev().str(), name_scope())); } // PASS void exprAttrib() { consume(TK("@id")); ctx()->s_expr.push( - expr_prev_line(ctx()->s_expr.popx(), prev().str()) + make_expr(ctx()->s_expr.popx(), prev().str()) ); } // PASS void exprSubscr() { - auto e = expr_prev_line(); + auto e = make_expr(); std::vector items; do { EXPR_TUPLE(); @@ -477,7 +471,7 @@ private: e->b = std::move(items[0]); break; case 2: case 3: { - auto slice = expr_prev_line(); + auto slice = make_expr(); slice->start = std::move(items[0]); slice->stop = std::move(items[1]); if(items.size()==3){ @@ -492,7 +486,7 @@ private: // PASS void exprLiteral0() { - ctx()->s_expr.push(expr_prev_line(prev().type)); + ctx()->s_expr.push(make_expr(prev().type)); } void compile_block_body() { @@ -708,15 +702,6 @@ private: ctx()->emit(OP_ASSERT, BC_NOARG, kw_line); consume_end_stmt(); break; - case TK("del"): - EXPR_TUPLE(); - Expr_ e = ctx()->s_expr.popx(); - switch(e->ref_type()){ - case EXPR_NAME_REF: - } - ctx()->emit(OP_DELETE_REF, BC_NOARG, kw_line); - consume_end_stmt(); - break; case TK("global"): do { consume(TK("@id")); @@ -735,6 +720,13 @@ private: ctx()->emit(OP_RAISE, dummy_t, kw_line); consume_end_stmt(); } break; + case TK("del"): { + EXPR_TUPLE(); + Expr_ e = ctx()->s_expr.popx(); + bool ok = e->emit_del(ctx()); + if(!ok) SyntaxError(); + consume_end_stmt(); + } break; case TK("with"): { EXPR(true); consume(TK("as")); diff --git a/src/expr.h b/src/expr.h index ba9ab990..f66e82c0 100644 --- a/src/expr.h +++ b/src/expr.h @@ -11,25 +11,20 @@ namespace pkpy{ struct CodeEmitContext; -enum ExprRefType{ - EXPR_NO_REF, - EXPR_NAME_REF, - EXPR_ATTR_REF, - EXPR_INDEX_REF, - EXPR_STARRED_REF, - EXPR_TUPLE_REF -}; - struct Expr{ int line = 0; virtual ~Expr() = default; virtual void emit(CodeEmitContext* ctx) = 0; virtual Str str() const = 0; - virtual std::vector children() = 0; - virtual ExprRefType ref_type() const { - return EXPR_NO_REF; - } + virtual std::vector children() const { return {}; } + virtual bool is_starred() const { return false; } + + // for OP_DELETE_XXX + virtual bool emit_del(CodeEmitContext* ctx) { return false; } + + // for OP_STORE_XXX + virtual bool emit_store(CodeEmitContext* ctx) { return false; } }; struct CodeEmitContext{ @@ -67,13 +62,12 @@ struct CodeEmitContext{ void emit_expr(){ if(s_expr.size() != 1) UNREACHABLE(); Expr_ expr = s_expr.popx(); - // emit - // ... + expr->emit(this); } int emit(Opcode opcode, int arg, int line) { co->codes.push_back( - Bytecode{(uint8_t)opcode, (uint16_t)curr_block_i, arg, line} + Bytecode{(uint16_t)opcode, (uint16_t)curr_block_i, arg, line} ); int i = co->codes.size() - 1; if(line==BC_KEEPLINE && i>=1) co->codes[i].line = co->codes[i-1].line; @@ -91,13 +85,11 @@ struct CodeEmitContext{ return true; } - int add_name(StrName name, NameScope scope){ - if(scope == NAME_LOCAL && co->global_names.count(name)) scope = NAME_GLOBAL; - auto p = std::make_pair(name, scope); + int add_name(StrName name){ for(int i=0; inames.size(); i++){ - if(co->names[i] == p) return i; + if(co->names[i] == name) return i; } - co->names.push_back(p); + co->names.push_back(name); return co->names.size() - 1; } @@ -107,7 +99,7 @@ struct CodeEmitContext{ } }; - +// PASS struct NameExpr: Expr{ Str name; NameScope scope; @@ -117,59 +109,99 @@ struct NameExpr: Expr{ Str str() const override { return "$" + name; } void emit(CodeEmitContext* ctx) override { - int index = ctx->add_name(name, scope); + int index = ctx->add_name(name); ctx->emit(OP_LOAD_NAME, index, line); } - ExprRefType ref_type() const override { - return EXPR_NAME_REF; + bool emit_del(CodeEmitContext* ctx) override { + int index = ctx->add_name(name); + switch(scope){ + case NAME_LOCAL: + ctx->emit(OP_DELETE_LOCAL, index, line); + break; + case NAME_GLOBAL: + ctx->emit(OP_DELETE_GLOBAL, index, line); + break; + default: UNREACHABLE(); break; + } + return true; + } + + bool emit_store(CodeEmitContext* ctx) override { + int index = ctx->add_name(name); + switch(scope){ + case NAME_LOCAL: + ctx->emit(OP_STORE_LOCAL, index, line); + break; + case NAME_GLOBAL: + ctx->emit(OP_STORE_GLOBAL, index, line); + break; + default: UNREACHABLE(); break; + } + return true; } }; - +// *号运算符,作为左值和右值效果不同 struct StarredExpr: Expr{ Expr_ child; StarredExpr(Expr_&& child): child(std::move(child)) {} Str str() const override { return "*"; } + std::vector children() const override { return {child.get()}; } + + bool is_starred() const override { return true; } + void emit(CodeEmitContext* ctx) override { child->emit(ctx); - ctx->emit(OP_UNARY_STAR, (int)false, line); + // as a rvalue, we should do unpack here + //ctx->emit(OP_UNARY_STAR, (int)false, line); } - ExprRefType ref_type() const override { - return EXPR_STARRED_REF; + bool emit_store(CodeEmitContext* ctx) override { + child->emit(ctx); + // as a lvalue, we should do pack here + //ctx->emit(OP_UNARY_STAR, (int)true, line); + return true; } }; - +// PASS struct NegatedExpr: Expr{ Expr_ child; NegatedExpr(Expr_&& child): child(std::move(child)) {} Str str() const override { return "-"; } + std::vector children() const override { return {child.get()}; } + void emit(CodeEmitContext* ctx) override { child->emit(ctx); ctx->emit(OP_UNARY_NEGATIVE, BC_NOARG, line); } }; +// PASS struct NotExpr: Expr{ Expr_ child; NotExpr(Expr_&& child): child(std::move(child)) {} Str str() const override { return "not"; } + std::vector children() const override { return {child.get()}; } + void emit(CodeEmitContext* ctx) override { child->emit(ctx); ctx->emit(OP_UNARY_NOT, BC_NOARG, line); } }; +// PASS struct AndExpr: Expr{ Expr_ lhs; Expr_ rhs; Str str() const override { return "and"; } + std::vector children() const override { return {lhs.get(), rhs.get()}; } + void emit(CodeEmitContext* ctx) override { lhs->emit(ctx); int patch = ctx->emit(OP_JUMP_IF_FALSE_OR_POP, BC_NOARG, line); @@ -178,11 +210,14 @@ struct AndExpr: Expr{ } }; +// PASS struct OrExpr: Expr{ Expr_ lhs; Expr_ rhs; Str str() const override { return "or"; } + std::vector children() const override { return {lhs.get(), rhs.get()}; } + void emit(CodeEmitContext* ctx) override { lhs->emit(ctx); int patch = ctx->emit(OP_JUMP_IF_TRUE_OR_POP, BC_NOARG, line); @@ -249,12 +284,18 @@ struct LiteralExpr: Expr{ } }; +// PASS struct SliceExpr: Expr{ Expr_ start; Expr_ stop; Expr_ step; Str str() const override { return "slice()"; } + std::vector children() const override { + // may contain nullptr + return {start.get(), stop.get(), step.get()}; + } + void emit(CodeEmitContext* ctx) override { if(start){ start->emit(ctx); @@ -278,11 +319,30 @@ struct SliceExpr: Expr{ } }; +struct DictItemExpr: Expr{ + Expr_ key; + Expr_ value; + Str str() const override { return "k:v"; } + std::vector children() const override { return {key.get(), value.get()}; } + + void emit(CodeEmitContext* ctx) override { + key->emit(ctx); + value->emit(ctx); + ctx->emit(OP_BUILD_TUPLE, 2, line); + } +}; + struct SequenceExpr: Expr{ std::vector items; SequenceExpr(std::vector&& items): items(std::move(items)) {} virtual Opcode opcode() const = 0; + std::vector children() const override { + std::vector ret; + for(auto& item: items) ret.push_back(item.get()); + return ret; + } + void emit(CodeEmitContext* ctx) override { for(auto& item: items) item->emit(ctx); ctx->emit(opcode(), items.size(), line); @@ -308,8 +368,9 @@ struct TupleExpr: SequenceExpr{ Str str() const override { return "tuple()"; } Opcode opcode() const override { return OP_BUILD_TUPLE; } - ExprRefType ref_type() const override { - return EXPR_TUPLE_REF; + bool emit_store(CodeEmitContext* ctx) override { + // ... + return true; } }; @@ -318,14 +379,6 @@ struct CompExpr: Expr{ Expr_ vars; // loop vars Expr_ iter; // loop iter Expr_ cond; // optional if condition - virtual void emit_expr() = 0; -}; - -// a:b -struct DictItemExpr: Expr{ - Expr_ key; - Expr_ value; - Str str() const override { return "k:v"; } }; struct ListCompExpr: CompExpr{ @@ -345,7 +398,9 @@ struct LambdaExpr: Expr{ void emit(CodeEmitContext* ctx) override { VM* vm = ctx->vm; ctx->emit(OP_LOAD_FUNCTION, ctx->add_const(VAR(func)), line); - if(scope == NAME_LOCAL) ctx->emit(OP_SETUP_CLOSURE, BC_NOARG, BC_KEEPLINE); + if(scope == NAME_LOCAL){ + ctx->emit(OP_SETUP_CLOSURE, BC_NOARG, BC_KEEPLINE); + } } }; @@ -393,11 +448,21 @@ struct SubscrExpr: Expr{ void emit(CodeEmitContext* ctx) override{ a->emit(ctx); b->emit(ctx); - ctx->emit(OP_BUILD_INDEX, BC_NOARG, line); + ctx->emit(OP_LOAD_SUBSCR, BC_NOARG, line); } - ExprRefType ref_type() const override { - return EXPR_INDEX_REF; + bool emit_del(CodeEmitContext* ctx) override { + a->emit(ctx); + b->emit(ctx); + ctx->emit(OP_DELETE_SUBSCR, BC_NOARG, line); + return true; + } + + bool emit_store(CodeEmitContext* ctx) override { + a->emit(ctx); + b->emit(ctx); + ctx->emit(OP_STORE_SUBSCR, BC_NOARG, line); + return true; } }; @@ -408,16 +473,56 @@ struct AttribExpr: Expr{ AttribExpr(Expr_ a, Str&& b): a(std::move(a)), b(std::move(b)) {} Str str() const override { return "a.b"; } - ExprRefType ref_type() const override { - return EXPR_ATTR_REF; + void emit(CodeEmitContext* ctx) override{ + a->emit(ctx); + int index = ctx->add_name(b); + ctx->emit(OP_LOAD_ATTR, index, line); + } + + bool emit_del(CodeEmitContext* ctx) override { + a->emit(ctx); + int index = ctx->add_name(b); + ctx->emit(OP_DELETE_ATTR, index, line); + return true; + } + + bool emit_store(CodeEmitContext* ctx) override { + a->emit(ctx); + int index = ctx->add_name(b); + ctx->emit(OP_STORE_ATTR, index, line); + return true; } }; +// PASS struct CallExpr: Expr{ Expr_ callable; std::vector args; std::vector> kwargs; - Str str() const override { return "()"; } + Str str() const override { return "call(...)"; } + + std::vector children() const override { + std::vector ret; + for(auto& item: args) ret.push_back(item.get()); + // ...ignore kwargs for simplicity + return ret; + } + + bool need_unpack() const { + for(auto& item: args) if(item->is_starred()) return true; + return false; + } + + void emit(CodeEmitContext* ctx) override { + callable->emit(ctx); + int KWARGC = (int)kwargs.size(); + int ARGC = (int)args.size(); + if(KWARGC > 0){ + ctx->emit(need_unpack() ? OP_CALL_KWARGS_UNPACK : OP_CALL_KWARGS, (KWARGC<<16)|ARGC, line); + }else{ + ctx->emit(need_unpack() ? OP_CALL_UNPACK : OP_CALL, ARGC, line); + } + } }; struct BinaryExpr: Expr{ @@ -426,6 +531,10 @@ struct BinaryExpr: Expr{ Expr_ rhs; Str str() const override { return TK_STR(op); } + std::vector children() const override { + return {lhs.get(), rhs.get()}; + } + void emit(CodeEmitContext* ctx) override { lhs->emit(ctx); rhs->emit(ctx); @@ -459,13 +568,18 @@ struct BinaryExpr: Expr{ } }; +// PASS struct TernaryExpr: Expr{ Expr_ cond; Expr_ true_expr; Expr_ false_expr; Str str() const override { - return "cond ? true_expr : false_expr"; + return "cond ? t : f"; + } + + std::vector children() const override { + return {cond.get(), true_expr.get(), false_expr.get()}; } void emit(CodeEmitContext* ctx) override { diff --git a/src/frame.h b/src/frame.h index 98e872c9..e52aff00 100644 --- a/src/frame.h +++ b/src/frame.h @@ -53,34 +53,20 @@ struct Frame { // return ss.str(); // } - PyObject* pop(){ -#if DEBUG_EXTRA_CHECK - if(_data.empty()) throw std::runtime_error("_data.empty() is true"); -#endif - PyObject* v = _data.back(); - _data.pop_back(); - return v; - } - - void _pop(){ + void pop(){ #if DEBUG_EXTRA_CHECK if(_data.empty()) throw std::runtime_error("_data.empty() is true"); #endif _data.pop_back(); } - void try_deref(VM*, PyObject*&); - - PyObject* pop_value(VM* vm){ - PyObject* value = pop(); - try_deref(vm, value); - return value; - } - - PyObject* top_value(VM* vm){ - PyObject* value = top(); - try_deref(vm, value); - return value; + PyObject* popx(){ +#if DEBUG_EXTRA_CHECK + if(_data.empty()) throw std::runtime_error("_data.empty() is true"); +#endif + PyObject* ret = _data.back(); + _data.pop_back(); + return ret; } PyObject*& top(){ @@ -141,18 +127,9 @@ struct Frame { } } - Args pop_n_values_reversed(VM* vm, int n){ - Args v(n); - for(int i=n-1; i>=0; i--){ - v[i] = pop(); - try_deref(vm, v[i]); - } - return v; - } - Args pop_n_reversed(int n){ Args v(n); - for(int i=n-1; i>=0; i--) v[i] = pop(); + for(int i=n-1; i>=0; i--) v[i] = popx(); return v; } diff --git a/src/opcodes.h b/src/opcodes.h index 693a579d..97a45a22 100644 --- a/src/opcodes.h +++ b/src/opcodes.h @@ -71,7 +71,6 @@ OPCODE(BUILD_ATTR_REF) OPCODE(STORE_NAME) OPCODE(STORE_FUNCTION) OPCODE(STORE_REF) -OPCODE(DELETE_REF) OPCODE(TRY_BLOCK_ENTER) OPCODE(TRY_BLOCK_EXIT) @@ -89,4 +88,20 @@ OPCODE(BEGIN_CLASS) OPCODE(END_CLASS) OPCODE(STORE_CLASS_ATTR) +/**************************/ +OPCODE(LOAD_NAME) +OPCODE(LOAD_ATTR) +OPCODE(LOAD_SUBSCR) + +OPCODE(STORE_LOCAL) +OPCODE(STORE_GLOBAL) +OPCODE(STORE_ATTR) +OPCODE(STORE_SUBSCR) + +OPCODE(DELETE_LOCAL) +OPCODE(DELETE_GLOBAL) +OPCODE(DELETE_ATTR) +OPCODE(DELETE_SUBSCR) +/**************************/ + #endif \ No newline at end of file diff --git a/src/ref.h b/src/ref.h index 11b5efc5..ca33ad18 100644 --- a/src/ref.h +++ b/src/ref.h @@ -83,11 +83,6 @@ struct AttrRef : BaseRef { vm->setattr(obj, attr.name(), std::move(val)); } - void del(VM* vm, Frame* frame) const{ - if(!obj->is_attr_valid()) vm->TypeError("cannot delete attribute"); - if(!obj->attr().contains(attr.name())) vm->AttributeError(obj, attr.name()); - obj->attr().erase(attr.name()); - } }; struct IndexRef : BaseRef {