fix more leaks

This commit is contained in:
blueloveTH 2024-06-09 20:37:49 +08:00
parent 157e64e0d8
commit 274cd58b49

View File

@ -275,27 +275,25 @@ Error* Compiler::exprLambda() noexcept{
} }
Error* Compiler::exprOr() noexcept{ Error* Compiler::exprOr() noexcept{
int line = prev().line;
Error* err;
check(parse_expression(PREC_LOGICAL_OR + 1));
auto e = make_expr<OrExpr>(); auto e = make_expr<OrExpr>();
e->lhs = ctx()->s_popx(); e->line = line;
Error* err = parse_expression(PREC_LOGICAL_OR + 1);
if(err){
delete_expr(e);
return err;
}
e->rhs = ctx()->s_popx(); e->rhs = ctx()->s_popx();
e->lhs = ctx()->s_popx();
ctx()->s_push(e); ctx()->s_push(e);
return NULL; return NULL;
} }
Error* Compiler::exprAnd() noexcept{ Error* Compiler::exprAnd() noexcept{
int line = prev().line;
Error* err;
check(parse_expression(PREC_LOGICAL_AND + 1));
auto e = make_expr<AndExpr>(); auto e = make_expr<AndExpr>();
e->lhs = ctx()->s_popx(); e->line = line;
Error* err = parse_expression(PREC_LOGICAL_AND + 1);
if(err){
delete_expr(e);
return err;
}
e->rhs = ctx()->s_popx(); e->rhs = ctx()->s_popx();
e->lhs = ctx()->s_popx();
ctx()->s_push(e); ctx()->s_push(e);
return NULL; return NULL;
} }
@ -874,8 +872,7 @@ Error* Compiler::try_compile_assignment(bool* is_assign) noexcept{
case TK("&="): case TK("&="):
case TK("|="): case TK("|="):
case TK("^="): { case TK("^="): {
Expr* lhs_p = ctx()->s_top(); if(ctx()->s_top()->is_starred()) return SyntaxError();
if(lhs_p->is_starred()) return SyntaxError();
if(ctx()->is_compiling_class){ if(ctx()->is_compiling_class){
return SyntaxError("can't use inplace operator in class definition"); return SyntaxError("can't use inplace operator in class definition");
} }
@ -883,14 +880,18 @@ Error* Compiler::try_compile_assignment(bool* is_assign) noexcept{
// a[x] += 1; a and x should be evaluated only once // a[x] += 1; a and x should be evaluated only once
// a.x += 1; a should be evaluated only once // a.x += 1; a should be evaluated only once
// -1 to remove =; inplace=true // -1 to remove =; inplace=true
// TODO: memory leak on error here! int line = prev().line;
BinaryExpr* e = make_expr<BinaryExpr>(prev().type - 1, true); TokenIndex op = prev().type-1;
e->lhs = ctx()->s_popx(); // [lhs]
check(EXPR_TUPLE()); check(EXPR_TUPLE()); // [lhs, rhs]
e->rhs = ctx()->s_popx(); if(ctx()->s_top()->is_starred()) return SyntaxError();
if(e->rhs->is_starred()) return SyntaxError(); BinaryExpr* e = make_expr<BinaryExpr>(op, true);
e->line = line;
e->rhs = ctx()->s_popx(); // [lhs]
e->lhs = ctx()->s_popx(); // []
e->emit_(ctx()); e->emit_(ctx());
bool ok = lhs_p->emit_store_inplace(ctx()); bool ok = e->lhs->emit_store_inplace(ctx());
delete_expr(e);
if(!ok) return SyntaxError(); if(!ok) return SyntaxError();
*is_assign = true; *is_assign = true;
return NULL; return NULL;
@ -1010,8 +1011,8 @@ Error* Compiler::compile_stmt() noexcept{
} break; } break;
case TK("del"): { case TK("del"): {
check(EXPR_TUPLE()); check(EXPR_TUPLE());
Expr* e = ctx()->s_popx(); if(!ctx()->s_top()->emit_del(ctx())) return SyntaxError();
if(!e->emit_del(ctx())) return SyntaxError(); ctx()->s_pop();
consume_end_stmt(); consume_end_stmt();
} break; } break;
case TK("with"): { case TK("with"): {
@ -1026,7 +1027,9 @@ Error* Compiler::compile_stmt() noexcept{
ctx()->emit_(OP_WITH_ENTER, BC_NOARG, prev().line); ctx()->emit_(OP_WITH_ENTER, BC_NOARG, prev().line);
// [ <expr> <expr>.__enter__() ] // [ <expr> <expr>.__enter__() ]
if(as_name) { if(as_name) {
if(!as_name->emit_store(ctx())) return SyntaxError(); bool ok = as_name->emit_store(ctx());
delete_expr(as_name);
if(!ok) return SyntaxError();
} else { } else {
ctx()->emit_(OP_POP_TOP, BC_NOARG, BC_KEEPLINE); ctx()->emit_(OP_POP_TOP, BC_NOARG, BC_KEEPLINE);
} }
@ -1097,8 +1100,7 @@ Error* Compiler::compile_stmt() noexcept{
Error* Compiler::consume_type_hints() noexcept{ Error* Compiler::consume_type_hints() noexcept{
Error* err; Error* err;
check(EXPR()); check(EXPR());
Expr* e = ctx()->s_popx(); ctx()->s_pop();
delete_expr(e);
return NULL; return NULL;
} }
@ -1106,18 +1108,18 @@ Error* Compiler::compile_class(int decorators) noexcept{
Error* err; Error* err;
consume(TK("@id")); consume(TK("@id"));
int namei = StrName(prev().sv()).index; int namei = StrName(prev().sv()).index;
Expr* base = nullptr; bool has_base = false;
if(match(TK("("))) { if(match(TK("("))) {
if(is_expression()) { if(is_expression()) {
check(EXPR()); check(EXPR());
base = ctx()->s_popx(); has_base = true; // [base]
} }
consume(TK(")")); consume(TK(")"));
} }
if(base == nullptr) { if(!has_base) {
ctx()->emit_(OP_LOAD_NONE, BC_NOARG, prev().line); ctx()->emit_(OP_LOAD_NONE, BC_NOARG, prev().line);
} else { } else {
base->emit_(ctx()); ctx()->s_emit_top(); // []
} }
ctx()->emit_(OP_BEGIN_CLASS, namei, BC_KEEPLINE); ctx()->emit_(OP_BEGIN_CLASS, namei, BC_KEEPLINE);
@ -1225,8 +1227,9 @@ Error* Compiler::compile_function(int decorators) noexcept{
ctx()->s_emit_decorators(decorators); ctx()->s_emit_decorators(decorators);
if(!ctx()->is_compiling_class) { if(!ctx()->is_compiling_class) {
auto e = make_expr<NameExpr>(decl_name, name_scope()); NameExpr* e = make_expr<NameExpr>(decl_name, name_scope());
e->emit_store(ctx()); e->emit_store(ctx());
delete_expr(e);
} else { } else {
int index = StrName(decl_name).index; int index = StrName(decl_name).index;
ctx()->emit_(OP_STORE_CLASS_ATTR, index, prev().line); ctx()->emit_(OP_STORE_CLASS_ATTR, index, prev().line);