Apply formating to all files. CLeanup

This commit is contained in:
IlyaShurupov 2023-10-22 17:07:28 +03:00 committed by Ilya Shurupov
parent b4ae5dde77
commit 91fb72bd49
928 changed files with 14515 additions and 21479 deletions

View file

@ -1,40 +1,36 @@
#include "NewPlacement.hpp"
#include "interpreter/callstack.h"
#include "interpreter/bytecode.h"
#include "primitives/methodobject.h"
using namespace obj;
void CallStack::enter(const CallStack::CallFrame& frame) {
if (mStack.size()) {
auto& last_frame = mStack.last();
last_frame.mIp = last_frame.mMethod->mScript->mBytecode.mInstructionIdx;
}
frame.mMethod->mScript->mBytecode.mArgumentsLoaded = 0;
frame.mMethod->mScript->mBytecode.mInstructionIdx = 0;
obj::NDO->refinc(frame.mMethod);
mStack.append(frame);
}
void CallStack::leave() {
auto frame = mStack.last();
obj::NDO->destroy(frame.mMethod);
mStack.pop();
if (mStack.size()) {
auto& last_frame = mStack.last();
last_frame.mMethod->mScript->mBytecode.mInstructionIdx = last_frame.mIp;
}
}
ByteCode* CallStack::getBytecode() {
return &mStack.last().mMethod->mScript->mBytecode;
}
tp::halni CallStack::len() const {
return mStack.size();
}
#include "NewPlacement.hpp"
#include "interpreter/callstack.h"
#include "interpreter/bytecode.h"
#include "primitives/methodobject.h"
using namespace obj;
void CallStack::enter(const CallStack::CallFrame& frame) {
if (mStack.size()) {
auto& last_frame = mStack.last();
last_frame.mIp = last_frame.mMethod->mScript->mBytecode.mInstructionIdx;
}
frame.mMethod->mScript->mBytecode.mArgumentsLoaded = 0;
frame.mMethod->mScript->mBytecode.mInstructionIdx = 0;
obj::NDO->refinc(frame.mMethod);
mStack.append(frame);
}
void CallStack::leave() {
auto frame = mStack.last();
obj::NDO->destroy(frame.mMethod);
mStack.pop();
if (mStack.size()) {
auto& last_frame = mStack.last();
last_frame.mMethod->mScript->mBytecode.mInstructionIdx = last_frame.mIp;
}
}
ByteCode* CallStack::getBytecode() { return &mStack.last().mMethod->mScript->mBytecode; }
tp::halni CallStack::len() const { return mStack.size(); }

File diff suppressed because it is too large Load diff

View file

@ -1,384 +1,371 @@
#include "Utils.hpp"
#include "interpreter/opcodes.h"
namespace obj {
OpcodeInfos gOpcodeInfos;
};
using namespace obj;
#define CONST_IDX_BYTES 2
#define OP(opcode, name, desc, ops, params) \
add(opcode, { #name, #desc, ops, params } );
OpcodeInfos::OperandsInfo::OperandsInfo() {}
OpcodeInfos::OperandsInfo::OperandsInfo(tp::InitialierList<Operand> list) {
DEBUG_ASSERT(MAX_OPERANDS >= list.size());
for (auto item : list) {
buff[len] = item;
len++;
}
}
OpcodeInfos::ParamsInfo::ParamsInfo() {}
OpcodeInfos::ParamsInfo::ParamsInfo(tp::InitialierList<Param> list) {
DEBUG_ASSERT(MAX_PARAMS >= list.size());
for (auto item : list) {
buff[len] = item;
len++;
}
}
tp::uint1 OpcodeInfos::OpInfo::opsize() {
tp::uint1 out = 1;
for (auto i = 0; i < params.len; i++) {
out += params.buff[i].bytes;
}
return out;
}
OpcodeInfos::OpcodeInfos() {
add(OpCode::NONE, { "NONE", "Does Nothing" });
add(OpCode::HALT, { "HALT", "Halts for 3 sec" });
add(OpCode::TERMINATE, { "TERMINATE", "Terminates the process" });
add(OpCode::DEF_LOCAL, {
.name = "DEF LOCAL",
.desc = "Adds object to the locals",
.operands = {
{ "str", "local id" },
{ "any", "object to be local" }
}
}
);
add(OpCode::LOAD_CONST, {
.name = "LOAD CONST",
.desc = "Loads const object from the const pool",
.params = {
{ "const obj idx", CONST_IDX_BYTES },
}
}
);
add(OpCode::LOAD_LOCAL, {
.name = "LOAD LOCAL",
.desc = "Loads local object from the locals",
.params = {
{ "idx of const StringObject - represents name id", CONST_IDX_BYTES },
}
}
);
add(OpCode::IGNORE, {
.name = "IGNORE",
.desc = "Ignores returned object by destroying it",
}
);
add(OpCode::SCOPE_IN, {
.name = "SCOPE IN",
.desc = "Enters new scope",
}
);
add(OpCode::SCOPE_OUT, {
.name = "SCOPE OUT",
.desc = "Leaves current scope",
}
);
add(OpCode::CALL, {
.name = "CALL",
.desc = "Leaves current scope",
.operands = {
{ "method", "method object" },
}
}
);
add(OpCode::RETURN_OBJ, {
.name = "RETURN OBJ",
.desc = "Returns Operand",
.operands = {
{ "any", "object to be returned" },
}
}
);
add(OpCode::RETURN, {
.name = "RETURN",
.desc = "Returns Null Object",
}
);
add(OpCode::CHILD, {
.name = "CHILD",
.desc = "Retrieves child from class",
.operands = {
{ "str", "child id" },
{ "class", "parent class" },
},
.params = {
{ "is method ?", 1 }
}
}
);
add(OpCode::PUSH_ARGS, {
.name = "PUSH ARGS",
.desc = "Pushes Separator on the OperandsStack",
.params = {
{ "length to chech number of args", 1 }
}
}
);
add(OpCode::SAVE_ARGS, {
.name = "SAVE ARGS",
.desc = "Pushes operands to locals",
.params = {
{ "number of arguments in function defenition", 1 }
}
}
);
add(OpCode::OBJ_CREATE_LOCAL, {
.name = "CREATE LOCAL OBJ",
.desc = "creates object of given type and adds it to the locals",
.operands = {
{ "str", "types" },
{ "str", "name id" },
}
}
);
add(OpCode::OBJ_CREATE, {
.name = "CREATE OBJ",
.desc = "creates object of given type",
.operands = {
{ "str", "types" },
}
}
);
add(OpCode::OBJ_COPY, {
.name = "COPY",
.desc = "Copies objects",
.operands = {
{ "any", "self" },
{ "any", "target" },
}
}
);
add(OpCode::OBJ_SAVE, {
.name = "SAVE",
.desc = "Saves object to a file",
.operands = {
{ "str", "path" },
{ "any", "self" },
}
}
);
add(OpCode::OBJ_LOAD, {
.name = "LOAD",
.desc = "loads object from a file",
.operands = {
{ "str", "path" },
{ "any", "self" },
}
}
);
add(OpCode::OBJ_ADD, {
.name = "ADD",
.desc = "Adds objects of the same type that supports ariphmetics",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::OBJ_SUB, {
.name = "SUB",
.desc = "Subtruts objects of the same type that supports ariphmetics",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::OBJ_MUL, {
.name = "MUL",
.desc = "Multiplies objects of the same type that supports ariphmetics",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::OBJ_DIV, {
.name = "DIV",
.desc = "Divides objects of the same type that supports ariphmetics",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::AND, {
.name = "AND",
.desc = "Logical AND of objects of the same type that supports boolean ariphmetics",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::OR, {
.name = "OR",
.desc = "Logical OR of objects of the same type that supports boolean ariphmetics",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::EQUAL, {
.name = "EQUAL",
.desc = "Compares objects",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::NOT_EQUAL, {
.name = "NOT EQUAL",
.desc = "Compares objects and inverts the resault",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::MORE, {
.name = "MORE",
.desc = " > ",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::LESS, {
.name = "LESS",
.desc = " < ",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::EQUAL_OR_MORE, {
.name = "GRATER OR EQUAL",
.desc = " >= ",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::EQUAL_OR_LESS, {
.name = "LESS OR EQUAL",
.desc = " <= ",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::NOT, {
.name = "NOT",
.desc = "Inverts the object bolean representation",
.operands = {
{ "any", "self" },
}
}
);
add(OpCode::JUMP, {
.name = "JUMP",
.desc = "Offsets the instruction pointer",
.params = {
{ "ip offset unsigned", 2 },
}
}
);
add(OpCode::JUMP_R, {
.name = "JUMP R",
.desc = "Offsets the instruction pointer in reversed direction",
.params = {
{ "ip offset unsigned", 2 },
}
}
);
add(OpCode::JUMP_IF, {
.name = "JUMP IF",
.desc = "Offsets the instruction pointer if condition is met",
.operands = {
{ "any", "condition object" },
},
.params = {
{ "ip offset unsigned", 2 },
}
}
);
add(OpCode::JUMP_IF_R, {
.name = "JUMP IF R",
.desc = "Offsets the instruction pointer in reversed direction if condition is met",
.operands = {
{ "any", "condition object" },
},
.params = {
{ "ip offset unsigned", 2 },
}
}
);
add(OpCode::JUMP_IF_NOT, {
.name = "JUMP IF R",
.desc = "Offsets the instruction pointer if condition is NOT met",
.operands = {
{ "any", "condition object" },
},
.params = {
{ "ip offset unsigned", 2 },
}
}
);
add(OpCode::JUMP_IF_NOT_R, {
.name = "JUMP IF R",
.desc = "Offsets the instruction pointer in reversed direction if condition is NOT met",
.operands = {
{ "any", "condition object" },
},
.params = {
{ "ip offset unsigned", 2 },
}
}
);
add(OpCode::PRINT, {
.name = "PRINT",
.desc = "Prints the object string representation",
.operands = {
{ "any", "self" },
}
}
);
add(OpCode::CLASS_CONSTRUCT, {
.name = "CLASS CONSTRUCT",
.desc = "Creates class from the function execution state",
}
);
add(OpCode::SELF, {
.name = "SELF",
.desc = "retrieves parent class of the current method",
}
);
}
OpcodeInfos::OpInfo OpcodeInfos::fetch(OpCode code) {
DEBUG_ASSERT((tp::alni)code >= 0 && (tp::alni)code < (tp::alni)OpCode::END_OPCODES);
return buff[(tp::alni)code];
}
void OpcodeInfos::add(OpCode code, const OpInfo& info) {
buff[(tp::alni)code] = info;
}
#include "Utils.hpp"
#include "interpreter/opcodes.h"
namespace obj {
OpcodeInfos gOpcodeInfos;
};
using namespace obj;
#define CONST_IDX_BYTES 2
#define OP(opcode, name, desc, ops, params) add(opcode, { #name, #desc, ops, params });
OpcodeInfos::OperandsInfo::OperandsInfo() {}
OpcodeInfos::OperandsInfo::OperandsInfo(tp::InitialierList<Operand> list) {
DEBUG_ASSERT(MAX_OPERANDS >= list.size());
for (auto item : list) {
buff[len] = item;
len++;
}
}
OpcodeInfos::ParamsInfo::ParamsInfo() {}
OpcodeInfos::ParamsInfo::ParamsInfo(tp::InitialierList<Param> list) {
DEBUG_ASSERT(MAX_PARAMS >= list.size());
for (auto item : list) {
buff[len] = item;
len++;
}
}
tp::uint1 OpcodeInfos::OpInfo::opsize() {
tp::uint1 out = 1;
for (auto i = 0; i < params.len; i++) {
out += params.buff[i].bytes;
}
return out;
}
OpcodeInfos::OpcodeInfos() {
add(OpCode::NONE, { "NONE", "Does Nothing" });
add(OpCode::HALT, { "HALT", "Halts for 3 sec" });
add(OpCode::TERMINATE, { "TERMINATE", "Terminates the process" });
add(OpCode::DEF_LOCAL, { .name = "DEF LOCAL", .desc = "Adds object to the locals", .operands = { { "str", "local id" }, { "any", "object to be local" } } });
add(OpCode::LOAD_CONST, {
.name = "LOAD CONST",
.desc = "Loads const object from the const pool",
.params = {
{ "const obj idx", CONST_IDX_BYTES },
}
}
);
add(OpCode::LOAD_LOCAL, {
.name = "LOAD LOCAL",
.desc = "Loads local object from the locals",
.params = {
{ "idx of const StringObject - represents name id", CONST_IDX_BYTES },
}
}
);
add(
OpCode::IGNORE,
{
.name = "IGNORE",
.desc = "Ignores returned object by destroying it",
}
);
add(
OpCode::SCOPE_IN,
{
.name = "SCOPE IN",
.desc = "Enters new scope",
}
);
add(
OpCode::SCOPE_OUT,
{
.name = "SCOPE OUT",
.desc = "Leaves current scope",
}
);
add(OpCode::CALL, {
.name = "CALL",
.desc = "Leaves current scope",
.operands = {
{ "method", "method object" },
}
}
);
add(OpCode::RETURN_OBJ, {
.name = "RETURN OBJ",
.desc = "Returns Operand",
.operands = {
{ "any", "object to be returned" },
}
}
);
add(
OpCode::RETURN,
{
.name = "RETURN",
.desc = "Returns Null Object",
}
);
add(OpCode::CHILD, {
.name = "CHILD",
.desc = "Retrieves child from class",
.operands = {
{ "str", "child id" },
{ "class", "parent class" },
},
.params = {
{ "is method ?", 1 }
}
}
);
add(OpCode::PUSH_ARGS, { .name = "PUSH ARGS", .desc = "Pushes Separator on the OperandsStack", .params = { { "length to chech number of args", 1 } } });
add(OpCode::SAVE_ARGS, { .name = "SAVE ARGS", .desc = "Pushes operands to locals", .params = { { "number of arguments in function defenition", 1 } } });
add(OpCode::OBJ_CREATE_LOCAL, {
.name = "CREATE LOCAL OBJ",
.desc = "creates object of given type and adds it to the locals",
.operands = {
{ "str", "types" },
{ "str", "name id" },
}
}
);
add(OpCode::OBJ_CREATE, {
.name = "CREATE OBJ",
.desc = "creates object of given type",
.operands = {
{ "str", "types" },
}
}
);
add(OpCode::OBJ_COPY, {
.name = "COPY",
.desc = "Copies objects",
.operands = {
{ "any", "self" },
{ "any", "target" },
}
}
);
add(OpCode::OBJ_SAVE, {
.name = "SAVE",
.desc = "Saves object to a file",
.operands = {
{ "str", "path" },
{ "any", "self" },
}
}
);
add(OpCode::OBJ_LOAD, {
.name = "LOAD",
.desc = "loads object from a file",
.operands = {
{ "str", "path" },
{ "any", "self" },
}
}
);
add(OpCode::OBJ_ADD, {
.name = "ADD",
.desc = "Adds objects of the same type that supports ariphmetics",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::OBJ_SUB, {
.name = "SUB",
.desc = "Subtruts objects of the same type that supports ariphmetics",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::OBJ_MUL, {
.name = "MUL",
.desc = "Multiplies objects of the same type that supports ariphmetics",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::OBJ_DIV, {
.name = "DIV",
.desc = "Divides objects of the same type that supports ariphmetics",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::AND, {
.name = "AND",
.desc = "Logical AND of objects of the same type that supports boolean ariphmetics",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::OR, {
.name = "OR",
.desc = "Logical OR of objects of the same type that supports boolean ariphmetics",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::EQUAL, {
.name = "EQUAL",
.desc = "Compares objects",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::NOT_EQUAL, {
.name = "NOT EQUAL",
.desc = "Compares objects and inverts the resault",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::MORE, {
.name = "MORE",
.desc = " > ",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::LESS, {
.name = "LESS",
.desc = " < ",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::EQUAL_OR_MORE, {
.name = "GRATER OR EQUAL",
.desc = " >= ",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::EQUAL_OR_LESS, {
.name = "LESS OR EQUAL",
.desc = " <= ",
.operands = {
{ "any", "left" },
{ "any", "right" },
}
}
);
add(OpCode::NOT, {
.name = "NOT",
.desc = "Inverts the object bolean representation",
.operands = {
{ "any", "self" },
}
}
);
add(OpCode::JUMP, {
.name = "JUMP",
.desc = "Offsets the instruction pointer",
.params = {
{ "ip offset unsigned", 2 },
}
}
);
add(OpCode::JUMP_R, {
.name = "JUMP R",
.desc = "Offsets the instruction pointer in reversed direction",
.params = {
{ "ip offset unsigned", 2 },
}
}
);
add(OpCode::JUMP_IF, {
.name = "JUMP IF",
.desc = "Offsets the instruction pointer if condition is met",
.operands = {
{ "any", "condition object" },
},
.params = {
{ "ip offset unsigned", 2 },
}
}
);
add(OpCode::JUMP_IF_R, {
.name = "JUMP IF R",
.desc = "Offsets the instruction pointer in reversed direction if condition is met",
.operands = {
{ "any", "condition object" },
},
.params = {
{ "ip offset unsigned", 2 },
}
}
);
add(OpCode::JUMP_IF_NOT, {
.name = "JUMP IF R",
.desc = "Offsets the instruction pointer if condition is NOT met",
.operands = {
{ "any", "condition object" },
},
.params = {
{ "ip offset unsigned", 2 },
}
}
);
add(OpCode::JUMP_IF_NOT_R, {
.name = "JUMP IF R",
.desc = "Offsets the instruction pointer in reversed direction if condition is NOT met",
.operands = {
{ "any", "condition object" },
},
.params = {
{ "ip offset unsigned", 2 },
}
}
);
add(OpCode::PRINT, {
.name = "PRINT",
.desc = "Prints the object string representation",
.operands = {
{ "any", "self" },
}
}
);
add(
OpCode::CLASS_CONSTRUCT,
{
.name = "CLASS CONSTRUCT",
.desc = "Creates class from the function execution state",
}
);
add(
OpCode::SELF,
{
.name = "SELF",
.desc = "retrieves parent class of the current method",
}
);
}
OpcodeInfos::OpInfo OpcodeInfos::fetch(OpCode code) {
DEBUG_ASSERT((tp::alni) code >= 0 && (tp::alni) code < (tp::alni) OpCode::END_OPCODES);
return buff[(tp::alni) code];
}
void OpcodeInfos::add(OpCode code, const OpInfo& info) { buff[(tp::alni) code] = info; }

View file

@ -1,32 +1,30 @@
#include "NewPlacement.hpp"
#include "interpreter/operandsstack.h"
using namespace obj;
OperandStack::OperandStack() {
mBuff = new Operand[MAX_STACK_SIZE];
mIdx = 0;
}
void OperandStack::push(Operand operand) {
ASSERT(MAX_STACK_SIZE - 1 > mIdx && "stack overflow");
mBuff[mIdx] = operand;
mIdx++;
}
void OperandStack::pop() {
ASSERT(mIdx != NULL && "stack overflow");
mIdx--;
}
Operand OperandStack::getOperand() {
auto ret = mBuff[mIdx - 1];
mIdx--;
return ret;
}
OperandStack::~OperandStack() {
delete[] mBuff;
}
#include "NewPlacement.hpp"
#include "interpreter/operandsstack.h"
using namespace obj;
OperandStack::OperandStack() {
mBuff = new Operand[MAX_STACK_SIZE];
mIdx = 0;
}
void OperandStack::push(Operand operand) {
ASSERT(MAX_STACK_SIZE - 1 > mIdx && "stack overflow");
mBuff[mIdx] = operand;
mIdx++;
}
void OperandStack::pop() {
ASSERT(mIdx != NULL && "stack overflow");
mIdx--;
}
Operand OperandStack::getOperand() {
auto ret = mBuff[mIdx - 1];
mIdx--;
return ret;
}
OperandStack::~OperandStack() { delete[] mBuff; }

View file

@ -1,90 +1,85 @@
#include "NewPlacement.hpp"
#include "interpreter/scopestack.h"
using namespace obj;
Scope::~Scope() {
for (auto local : mLocals) {
obj::NDO->destroy(local->val);
}
for (auto tmp : mTemps) {
obj::NDO->destroy(tmp.data());
}
}
obj::Object* ScopeStack::getLocalUtil(Scope& scope, tp::String* id) {
auto idx = scope.mLocals.presents(*id);
if (idx) {
return scope.mLocals.getSlotVal(idx);
}
else {
mIterIdx--;
Scope& parent_scope = mBuff[mIterIdx];
ASSERT(parent_scope.mChildReachable && "Undefined Local Reference");
return getLocalUtil(parent_scope, id);
}
}
ScopeStack::ScopeStack() {
mBuff = (Scope*) tp::HeapAllocGlobal::allocate(sizeof(Scope) * MAX_STACK_SIZE);
mIdx = 0;
mIterIdx = 0;
}
void ScopeStack::enterScope(bool aChildReachable) {
ASSERT(MAX_STACK_SIZE - 1 > mIdx && "stack overflow");
new (&mBuff[mIdx]) Scope();
mBuff[mIdx].mChildReachable = aChildReachable;
mIdx++;
}
void ScopeStack::leaveScope() {
ASSERT(mIdx != NULL && "stack overflow");
mBuff[mIdx - 1].~Scope();
mIdx--;
}
void ScopeStack::addTemp(obj::Object* tmp) {
obj::NDO->refinc(tmp);
mBuff[mIdx - 1].mTemps.pushBack(tmp);
}
void ScopeStack::popTemp() {
obj::NDO->destroy(mBuff[mIdx - 1].mTemps.last()->data);
mBuff[mIdx - 1].mTemps.popBack();
}
void ScopeStack::addTempReturn(obj::Object* ret) {
if (mIdx >= 2) {
obj::NDO->refinc(ret);
mBuff[mIdx - 2].mTemps.pushBack(ret);
}
}
void ScopeStack::addLocal(obj::Object* local, tp::String id) {
DEBUG_ASSERT(mIdx != 0 && "No scope given");
Scope::ObjDict& locals = mBuff[mIdx - 1].mLocals;
auto idx = locals.presents(id);
if (idx) {
obj::NDO->destroy(locals.getSlotVal(idx));
}
obj::NDO->refinc(local);
locals.put(id, local);
}
obj::Object* ScopeStack::getLocal(tp::String& str) {
mIterIdx = mIdx - 1;
return getLocalUtil(mBuff[mIdx - 1], &str);
}
Scope* ScopeStack::getCurrentScope() {
return &mBuff[mIdx - 1];
}
ScopeStack::~ScopeStack() {
tp::HeapAllocGlobal::deallocate(mBuff);
}
#include "NewPlacement.hpp"
#include "interpreter/scopestack.h"
using namespace obj;
Scope::~Scope() {
for (auto local : mLocals) {
obj::NDO->destroy(local->val);
}
for (auto tmp : mTemps) {
obj::NDO->destroy(tmp.data());
}
}
obj::Object* ScopeStack::getLocalUtil(Scope& scope, tp::String* id) {
auto idx = scope.mLocals.presents(*id);
if (idx) {
return scope.mLocals.getSlotVal(idx);
} else {
mIterIdx--;
Scope& parent_scope = mBuff[mIterIdx];
ASSERT(parent_scope.mChildReachable && "Undefined Local Reference");
return getLocalUtil(parent_scope, id);
}
}
ScopeStack::ScopeStack() {
mBuff = (Scope*) tp::HeapAllocGlobal::allocate(sizeof(Scope) * MAX_STACK_SIZE);
mIdx = 0;
mIterIdx = 0;
}
void ScopeStack::enterScope(bool aChildReachable) {
ASSERT(MAX_STACK_SIZE - 1 > mIdx && "stack overflow");
new (&mBuff[mIdx]) Scope();
mBuff[mIdx].mChildReachable = aChildReachable;
mIdx++;
}
void ScopeStack::leaveScope() {
ASSERT(mIdx != NULL && "stack overflow");
mBuff[mIdx - 1].~Scope();
mIdx--;
}
void ScopeStack::addTemp(obj::Object* tmp) {
obj::NDO->refinc(tmp);
mBuff[mIdx - 1].mTemps.pushBack(tmp);
}
void ScopeStack::popTemp() {
obj::NDO->destroy(mBuff[mIdx - 1].mTemps.last()->data);
mBuff[mIdx - 1].mTemps.popBack();
}
void ScopeStack::addTempReturn(obj::Object* ret) {
if (mIdx >= 2) {
obj::NDO->refinc(ret);
mBuff[mIdx - 2].mTemps.pushBack(ret);
}
}
void ScopeStack::addLocal(obj::Object* local, tp::String id) {
DEBUG_ASSERT(mIdx != 0 && "No scope given");
Scope::ObjDict& locals = mBuff[mIdx - 1].mLocals;
auto idx = locals.presents(id);
if (idx) {
obj::NDO->destroy(locals.getSlotVal(idx));
}
obj::NDO->refinc(local);
locals.put(id, local);
}
obj::Object* ScopeStack::getLocal(tp::String& str) {
mIterIdx = mIdx - 1;
return getLocalUtil(mBuff[mIdx - 1], &str);
}
Scope* ScopeStack::getCurrentScope() { return &mBuff[mIdx - 1]; }
ScopeStack::~ScopeStack() { tp::HeapAllocGlobal::deallocate(mBuff); }