Skip to content

Commit e084bcc

Browse files
committed
feat: improved management of space used by local variables on the stack
1 parent 1097560 commit e084bcc

File tree

8 files changed

+82
-76
lines changed

8 files changed

+82
-76
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
cmake_minimum_required(VERSION 3.15)
2-
project(Argon VERSION 0.5.0)
2+
project(Argon VERSION 0.5.1)
33

44
set(AR_MAJOR ${PROJECT_VERSION_MAJOR})
55
set(AR_MINOR ${PROJECT_VERSION_MINOR})

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
</p>
44

55
<p align="center">
6-
<a href="https://img.shields.io/badge/version-0.5.0--alpha-red">
7-
<img src="https://img.shields.io/badge/version-0.5.0--alpha-red" alt="Version 0.5.0-alpha">
6+
<a href="https://img.shields.io/badge/version-0.5.1--alpha-red">
7+
<img src="https://img.shields.io/badge/version-0.5.1--alpha-red" alt="Version 0.5.1-alpha">
88
</a>
99
<a href="https://www.apache.org/licenses/LICENSE-2.0">
1010
<img src="https://img.shields.io/badge/license-apache--2.0-blue" alt="Apache License 2.0">

argon/lang/compiler2/compiler2.cpp

+27-36
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,7 @@ void Compiler::CompileFor(const node::Loop *loop) {
306306

307307
CHECK_AST_NODE(node::type_ast_loop_, loop);
308308

309-
if (!this->unit_->symt->NewNestedTable())
310-
throw DatatypeException();
309+
this->unit_->EnterSub();
311310

312311
if (loop->init != nullptr)
313312
this->Compile(loop->init);
@@ -356,7 +355,7 @@ void Compiler::CompileFor(const node::Loop *loop) {
356355

357356
this->unit_->JBPop();
358357

359-
SymbolExitNested(this->unit_->symt);
358+
this->unit_->ExitSub(false);
360359

361360
this->unit_->BlockAppend(end);
362361
}
@@ -367,8 +366,7 @@ void Compiler::CompileForEach(const node::Loop *loop) {
367366

368367
CHECK_AST_NODE(node::type_ast_loop_, loop);
369368

370-
if (!this->unit_->symt->NewNestedTable())
371-
throw DatatypeException();
369+
this->unit_->EnterSub();
372370

373371
if ((end = BasicBlockNew()) == nullptr)
374372
throw DatatypeException();
@@ -407,7 +405,7 @@ void Compiler::CompileForEach(const node::Loop *loop) {
407405

408406
this->unit_->JBPop();
409407

410-
SymbolExitNested(this->unit_->symt);
408+
this->unit_->ExitSub(false);
411409

412410
this->unit_->BlockAppend(end);
413411

@@ -542,8 +540,7 @@ void Compiler::CompileIF(const node::Branch *branch) {
542540

543541
this->unit_->BlockNew();
544542

545-
if (!this->unit_->symt->NewNestedTable())
546-
throw DatatypeException();
543+
this->unit_->EnterSub();
547544

548545
if (merge)
549546
this->unit_->symt->stack->nested--;
@@ -560,22 +557,21 @@ void Compiler::CompileIF(const node::Branch *branch) {
560557
orelse = nullptr; // Avoid releasing it in case of an exception.
561558

562559
if (AR_TYPEOF(branch->orelse, node::type_ast_unary_)) {
563-
if (!this->unit_->symt->NewNestedTable())
564-
throw DatatypeException();
560+
this->unit_->EnterSub();
565561

566562
if (merge)
567563
this->unit_->symt->stack->nested--;
568564

569565
this->CompileBlock(branch->orelse, false);
570566

571-
SymbolExitNested(this->unit_->symt, merge);
567+
this->unit_->ExitSub(merge);
572568
} else if (AR_TYPEOF(branch->orelse, node::type_ast_branch_))
573569
this->CompileIF((const node::Branch *) branch->orelse);
574570
else
575571
throw CompilerException(kCompilerErrors[1], (int) branch->orelse->node_type, __FUNCTION__);
576572
}
577573

578-
SymbolExitNested(this->unit_->symt, merge);
574+
this->unit_->ExitSub(merge);
579575
} catch (...) {
580576
if (orelse != end) {
581577
BasicBlockDel(orelse);
@@ -819,8 +815,7 @@ void Compiler::CompileSwitchCase(const node::Binary *swcase, BasicBlock **ltest,
819815

820816
CHECK_AST_NODE(node::type_ast_switchcase_, swcase);
821817

822-
if (!this->unit_->symt->NewNestedTable())
823-
throw DatatypeException();
818+
this->unit_->EnterSub();
824819

825820
if ((*lbody)->size > 0) {
826821
// Switch to bodies thread
@@ -879,7 +874,7 @@ void Compiler::CompileSwitchCase(const node::Binary *swcase, BasicBlock **ltest,
879874
if (!fallthrough)
880875
this->unit_->Emit(vm::OpCode::JMP, 0, end, nullptr);
881876

882-
SymbolExitNested(this->unit_->symt);
877+
this->unit_->ExitSub(false);
883878

884879
*lbody = this->unit_->bbb.current;
885880
}
@@ -1161,7 +1156,6 @@ void Compiler::IdentifierNew(String *name, const scanner::Loc *loc, SymbolType t
11611156
if (!sym)
11621157
throw DatatypeException();
11631158

1164-
auto *dest = this->unit_->names;
11651159
auto *p_sym = (SymbolT *) sym.Get();
11661160

11671161
p_sym->declared = true;
@@ -1174,36 +1168,33 @@ void Compiler::IdentifierNew(String *name, const scanner::Loc *loc, SymbolType t
11741168
}
11751169

11761170
if (p_sym->nested == 0) {
1177-
auto id = (unsigned short) (p_sym->id >= 0 ? p_sym->id : dest->length);
1171+
auto id = (unsigned short) (p_sym->id >= 0 ? p_sym->id : this->unit_->names->length);
11781172

11791173
if (emit)
11801174
this->unit_->Emit(vm::OpCode::NGV, (unsigned char) aflags, id, loc);
11811175

11821176
if (p_sym->id >= 0)
11831177
return;
1184-
} else {
1185-
dest = this->unit_->locals;
11861178

1187-
if (emit)
1188-
this->unit_->Emit(vm::OpCode::STLC, (int) dest->length, nullptr, loc);
1189-
}
1179+
p_sym->id = (short) this->unit_->names->length;
11901180

1191-
ArObject *arname;
1181+
if (!ListAppend(this->unit_->names, (ArObject *) name))
1182+
throw DatatypeException();
11921183

1193-
if (p_sym->id >= 0)
1194-
arname = ListGet(!p_sym->free ? this->unit_->names : this->unit_->enclosed, p_sym->id);
1195-
else
1196-
arname = (ArObject *) IncRef(name);
1184+
return;
1185+
}
11971186

1198-
p_sym->id = (short) dest->length;
1187+
if (emit)
1188+
this->unit_->Emit(vm::OpCode::STLC, (int) this->unit_->local.current, nullptr, loc);
11991189

1200-
if (!ListAppend(dest, arname)) {
1201-
Release(arname);
1190+
p_sym->id = (short) this->unit_->local.current;
12021191

1203-
throw DatatypeException();
1204-
}
1192+
this->unit_->local.current++;
1193+
if (this->unit_->local.required < this->unit_->local.current)
1194+
this->unit_->local.required++;
12051195

1206-
Release(arname);
1196+
if (!emit && !ListAppend(this->unit_->lnames, (ArObject *) name))
1197+
throw DatatypeException();
12071198
}
12081199

12091200
void Compiler::IdentifierNew(const node::Unary *id, SymbolType type, AttributeFlag aflags, bool emit) {
@@ -1259,14 +1250,14 @@ void Compiler::CompileBlock(const node::Node *node, bool sub) {
12591250
if (!iter)
12601251
throw DatatypeException();
12611252

1262-
if (sub && !this->unit_->symt->NewNestedTable())
1263-
throw DatatypeException();
1253+
if (sub)
1254+
this->unit_->EnterSub();
12641255

12651256
while ((stmt = IteratorNext(iter.Get())))
12661257
this->Compile((const node::Node *) stmt.Get());
12671258

12681259
if (sub)
1269-
SymbolExitNested(this->unit_->symt);
1260+
this->unit_->ExitSub(false);
12701261
}
12711262

12721263
void Compiler::CompileCall(const node::Call *call) {

argon/lang/compiler2/transl_unit.cpp

+5-7
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
//
33
// Licensed under the Apache License v2.0
44

5-
#include <argon/lang/exception.h>
6-
75
#include <argon/lang/compiler2/optimizer/optimizer.h>
86

97
#include <argon/lang/compiler2/transl_unit.h>
@@ -63,7 +61,7 @@ Code *TranslationUnit::Assemble(String *docs, OptimizationLevel level) {
6361
this->ComputeAssemblyLength(&instr_sz, &line_sz);
6462

6563
if (instr_sz == 0) {
66-
if ((code = CodeNew(this->statics, this->names, this->locals, this->enclosed)) == nullptr)
64+
if ((code = CodeNew(this->statics, this->names, this->lnames, this->enclosed, this->local.required)) == nullptr)
6765
throw DatatypeException();
6866

6967
return code->SetInfo(this->name, this->qname, docs);
@@ -145,7 +143,7 @@ Code *TranslationUnit::Assemble(String *docs, OptimizationLevel level) {
145143
}
146144
}
147145

148-
if ((code = CodeNew(this->statics, this->names, this->locals, this->enclosed)) == nullptr) {
146+
if ((code = CodeNew(this->statics, this->names, this->lnames, this->enclosed, this->local.required)) == nullptr) {
149147
vm::memory::Free(instr_buf);
150148
vm::memory::Free(line_buf);
151149

@@ -392,7 +390,7 @@ TranslationUnit *argon::lang::compiler2::TranslationUnitNew(TranslationUnit *pre
392390
if ((tu->names = ListNew()) == nullptr)
393391
goto ERROR;
394392

395-
if ((tu->locals = ListNew()) == nullptr)
393+
if ((tu->lnames = ListNew()) == nullptr)
396394
goto ERROR;
397395

398396
if ((tu->enclosed = ListNew()) == nullptr)
@@ -410,7 +408,7 @@ TranslationUnit *argon::lang::compiler2::TranslationUnitNew(TranslationUnit *pre
410408
Release(tu->statics_map);
411409
Release(tu->statics);
412410
Release(tu->names);
413-
Release(tu->locals);
411+
Release(tu->lnames);
414412

415413
argon::vm::memory::Free(tu->statics_usg_count);
416414
argon::vm::memory::Free(tu);
@@ -448,7 +446,7 @@ TranslationUnit *argon::lang::compiler2::TranslationUnitDel(TranslationUnit *uni
448446
Release(unit->statics_map);
449447
Release(unit->statics);
450448
Release(unit->names);
451-
Release(unit->locals);
449+
Release(unit->lnames);
452450
Release(unit->enclosed);
453451

454452
argon::vm::memory::Free(unit->statics_usg_count);

argon/lang/compiler2/transl_unit.h

+21-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#include <argon/vm/datatype/arstring.h>
99
#include <argon/vm/datatype/code.h>
1010

11+
#include <argon/lang/exception.h>
12+
1113
#include <argon/lang/scanner/token.h>
1214

1315
#include <argon/lang/compiler2/basicblock.h>
@@ -41,8 +43,8 @@ namespace argon::lang::compiler2 {
4143
/// External variables (global scope).
4244
vm::datatype::List *names;
4345

44-
/// Local variables (function/cycle scope).
45-
vm::datatype::List *locals;
46+
/// Local variables names (function parameters)
47+
vm::datatype::List *lnames;
4648

4749
/// Closure.
4850
vm::datatype::List *enclosed;
@@ -56,6 +58,11 @@ namespace argon::lang::compiler2 {
5658
unsigned int current;
5759
} stack;
5860

61+
struct {
62+
unsigned short required;
63+
unsigned short current;
64+
} local;
65+
5966
struct {
6067
unsigned short required;
6168
unsigned short current;
@@ -107,6 +114,13 @@ namespace argon::lang::compiler2 {
107114
this->Emit(vm::OpCode::POP, 0, nullptr, nullptr);
108115
}
109116

117+
void EnterSub() const {
118+
if (!this->symt->NewNestedTable())
119+
throw DatatypeException();
120+
121+
this->symt->stack->id = (short) this->local.current;
122+
}
123+
110124
void EnterSync(const scanner::Loc *loc) {
111125
this->Emit(vm::OpCode::SYNC, loc);
112126

@@ -115,6 +129,11 @@ namespace argon::lang::compiler2 {
115129
this->sync_stack.required = this->sync_stack.current;
116130
}
117131

132+
void ExitSub(bool merge) {
133+
this->local.current = this->symt->stack->id;
134+
SymbolExitNested(this->symt, merge);
135+
}
136+
118137
void ExitSync() {
119138
this->Emit(vm::OpCode::UNSYNC, nullptr);
120139

argon/vm/datatype/code.cpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
//
33
// Licensed under the Apache License v2.0
44

5-
#include <argon/vm/datatype/arstring.h>
65
#include <argon/vm/datatype/boolean.h>
76
#include <argon/vm/datatype/hash_magic.h>
87

@@ -53,7 +52,7 @@ bool code_dtor(Code *self) {
5352

5453
Release(self->statics);
5554
Release(self->names);
56-
Release(self->locals);
55+
Release(self->lnames);
5756
Release(self->enclosed);
5857

5958
argon::vm::memory::Free((void *) self->instr);
@@ -88,7 +87,7 @@ TypeInfo CodeType = {
8887
};
8988
const TypeInfo *argon::vm::datatype::type_code_ = &CodeType;
9089

91-
Code *argon::vm::datatype::CodeNew(List *statics, List *names, List *locals, List *enclosed) {
90+
Code *argon::vm::datatype::CodeNew(List *statics, List *names, List *lnames, List *enclosed, unsigned short locals_sz) {
9291
auto *code = MakeObject<Code>(&CodeType);
9392

9493
if (code != nullptr) {
@@ -103,6 +102,7 @@ Code *argon::vm::datatype::CodeNew(List *statics, List *names, List *locals, Lis
103102
code->instr_sz = 0;
104103
code->sstack_sz = 0;
105104
code->stack_sz = 0;
105+
code->locals_sz = locals_sz;
106106
code->linfo_sz = 0;
107107

108108
if ((code->statics = TupleNew((ArObject *) statics)) == nullptr) {
@@ -115,7 +115,7 @@ Code *argon::vm::datatype::CodeNew(List *statics, List *names, List *locals, Lis
115115
return nullptr;
116116
}
117117

118-
if ((code->locals = TupleNew((ArObject *) locals)) == nullptr) {
118+
if ((code->lnames = TupleNew((ArObject *) lnames)) == nullptr) {
119119
Release(code);
120120
return nullptr;
121121
}
@@ -152,6 +152,8 @@ Code *argon::vm::datatype::CodeWrapFnCall(unsigned short argc, OpCodeCallMode mo
152152
code->instr_end = code->instr + instr_sz;
153153
code->instr_sz = instr_sz;
154154
code->stack_sz = argc + 1;
155+
code->sstack_sz = 0;
156+
code->locals_sz = 0;
155157

156158
code->linfo = nullptr;
157159
code->linfo_sz = 0;
@@ -161,7 +163,7 @@ Code *argon::vm::datatype::CodeWrapFnCall(unsigned short argc, OpCodeCallMode mo
161163
code->doc = nullptr;
162164
code->statics = nullptr;
163165
code->names = nullptr;
164-
code->locals = nullptr;
166+
code->lnames = nullptr;
165167
code->enclosed = nullptr;
166168
}
167169

0 commit comments

Comments
 (0)