clean up object module
This commit is contained in:
parent
4c66704830
commit
5d9e270aa9
68 changed files with 1223 additions and 1229 deletions
|
|
@ -2,12 +2,11 @@
|
|||
#include "primitives/MethodObject.hpp"
|
||||
#include "primitives/PrimitiveObjects.hpp"
|
||||
|
||||
using namespace obj;
|
||||
using namespace tp;
|
||||
using namespace BCgen;
|
||||
using namespace obj;
|
||||
|
||||
ConstObject::ConstObject() {}
|
||||
ConstObject::ConstObject(obj::Object* mObj) :
|
||||
ConstObject::ConstObject() = default;
|
||||
ConstObject::ConstObject(Object* mObj) :
|
||||
mObj(mObj) {}
|
||||
|
||||
ConstObjectsPool::~ConstObjectsPool() {
|
||||
|
|
@ -42,15 +41,15 @@ ConstObjectsPool::~ConstObjectsPool() {
|
|||
}
|
||||
}
|
||||
|
||||
ConstObject* ConstObjectsPool::registerObject(obj::Object* obj) {
|
||||
ConstObject* out = new ConstObject(obj);
|
||||
ConstObject* ConstObjectsPool::registerObject(Object* obj) {
|
||||
auto out = new ConstObject(obj);
|
||||
mTotalObjects++;
|
||||
return out;
|
||||
}
|
||||
|
||||
ConstObject* ConstObjectsPool::get(tp::alni val) {
|
||||
ConstObject* ConstObjectsPool::get(alni val) {
|
||||
auto idx = mIntegers.presents(val);
|
||||
ConstObject* const_obj = nullptr;
|
||||
ConstObject* const_obj;
|
||||
if (idx) {
|
||||
const_obj = mIntegers.getSlotVal(idx);
|
||||
} else {
|
||||
|
|
@ -62,7 +61,7 @@ ConstObject* ConstObjectsPool::get(tp::alni val) {
|
|||
|
||||
ConstObject* ConstObjectsPool::get(const std::string& val) {
|
||||
auto idx = mStrings.presents(val);
|
||||
ConstObject* const_obj = nullptr;
|
||||
ConstObject* const_obj;
|
||||
if (idx) {
|
||||
const_obj = mStrings.getSlotVal(idx);
|
||||
} else {
|
||||
|
|
@ -72,9 +71,9 @@ ConstObject* ConstObjectsPool::get(const std::string& val) {
|
|||
return const_obj;
|
||||
}
|
||||
|
||||
ConstObject* ConstObjectsPool::get(tp::alnf val) {
|
||||
ConstObject* ConstObjectsPool::get(alnf val) {
|
||||
auto idx = mFloats.presents(val);
|
||||
ConstObject* const_obj = nullptr;
|
||||
ConstObject* const_obj;
|
||||
if (idx) {
|
||||
const_obj = mFloats.getSlotVal(idx);
|
||||
} else {
|
||||
|
|
@ -100,17 +99,17 @@ ConstObject* ConstObjectsPool::get(bool val) {
|
|||
}
|
||||
}
|
||||
|
||||
ConstObject* ConstObjectsPool::addMethod(const std::string& method_id, obj::Object* method) {
|
||||
ASSERT(NDO_CAST(MethodObject, method) && "Object is not a method object");
|
||||
ASSERT(!mMethods.presents(method_id) && "Method Redefinition");
|
||||
ConstObject* ConstObjectsPool::addMethod(const std::string& method_id, Object* method) {
|
||||
ASSERT(NDO_CAST(MethodObject, method) && "Object is not a method object")
|
||||
ASSERT(!mMethods.presents(method_id) && "Method Redefinition")
|
||||
auto out = registerObject(method);
|
||||
mMethods.put(method_id, out);
|
||||
return out;
|
||||
}
|
||||
|
||||
void ConstObjectsPool::save(tp::Buffer<ConstData>& out) {
|
||||
void ConstObjectsPool::save(Buffer<ConstData>& out) {
|
||||
out.reserve(mTotalObjects);
|
||||
tp::alni data_idx = 0;
|
||||
alni data_idx = 0;
|
||||
for (auto obj : mMethods) {
|
||||
out[data_idx] = obj->val->mObj;
|
||||
obj->val->mConstIdx = data_idx;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
#include "compiler/Expressions.hpp"
|
||||
|
||||
#include <utility>
|
||||
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
using namespace BCgen;
|
||||
|
||||
Expression::Expression(Type type) :
|
||||
mType(type) {}
|
||||
|
|
@ -46,25 +48,25 @@ ExpressionList::~ExpressionList() {
|
|||
}
|
||||
}
|
||||
|
||||
ExpressionNew::ExpressionNew(const std::string& type) :
|
||||
ExpressionNew::ExpressionNew(std::string type) :
|
||||
Expression(Type::NEW),
|
||||
mNewType(type) {}
|
||||
mNewType(std::move(type)) {}
|
||||
|
||||
ExpressionNew::~ExpressionNew() = default;
|
||||
|
||||
ExpressionLocal::ExpressionLocal(const std::string& id) :
|
||||
ExpressionLocal::ExpressionLocal(std::string id) :
|
||||
Expression(Type::LOCAL),
|
||||
mLocalId(id) {}
|
||||
mLocalId(std::move(id)) {}
|
||||
|
||||
ExpressionLocal::~ExpressionLocal() = default;
|
||||
|
||||
ExpressionSelf::ExpressionSelf() :
|
||||
Expression(Type::SELF) {}
|
||||
|
||||
ExpressionChild::ExpressionChild(Expression* mParent, const std::string& id) :
|
||||
ExpressionChild::ExpressionChild(Expression* mParent, std::string id) :
|
||||
Expression(Type::CHILD),
|
||||
mParent(mParent),
|
||||
mLocalId(id) {}
|
||||
mLocalId(std::move(id)) {}
|
||||
|
||||
ExpressionChild::~ExpressionChild() { delete mParent; }
|
||||
|
||||
|
|
@ -79,38 +81,38 @@ ExpressionArithmetics::~ExpressionArithmetics() {
|
|||
delete mRight;
|
||||
}
|
||||
|
||||
ExpressionFunc::ExpressionFunc(const std::string& id) :
|
||||
ExpressionFunc::ExpressionFunc(std::string id) :
|
||||
Expression(Type::FUNC),
|
||||
mFuncId(id) {}
|
||||
mFuncId(std::move(id)) {}
|
||||
|
||||
ExpressionFunc::~ExpressionFunc() = default;
|
||||
|
||||
ExpressionConst::ExpressionConst(const std::string& val) :
|
||||
ExpressionConst::ExpressionConst(std::string val) :
|
||||
Expression(Type::CONST_EXPR),
|
||||
mConstType(STR),
|
||||
str(val) {}
|
||||
str(std::move(val)) {}
|
||||
|
||||
ExpressionConst::ExpressionConst(const char* val) :
|
||||
Expression(Type::CONST_EXPR),
|
||||
mConstType(STR),
|
||||
str(val) {}
|
||||
|
||||
ExpressionConst::ExpressionConst(tp::int4 val) :
|
||||
ExpressionConst::ExpressionConst(int4 val) :
|
||||
Expression(Type::CONST_EXPR),
|
||||
mConstType(INT),
|
||||
integer(val) {}
|
||||
|
||||
ExpressionConst::ExpressionConst(tp::flt4 val) :
|
||||
ExpressionConst::ExpressionConst(flt4 val) :
|
||||
Expression(Type::CONST_EXPR),
|
||||
mConstType(FLT),
|
||||
floating(val) {}
|
||||
|
||||
ExpressionConst::ExpressionConst(tp::alni val) :
|
||||
ExpressionConst::ExpressionConst(alni val) :
|
||||
Expression(Type::CONST_EXPR),
|
||||
mConstType(INT),
|
||||
integer(val) {}
|
||||
|
||||
ExpressionConst::ExpressionConst(tp::alnf val) :
|
||||
ExpressionConst::ExpressionConst(alnf val) :
|
||||
Expression(Type::CONST_EXPR),
|
||||
mConstType(FLT),
|
||||
floating(val) {}
|
||||
|
|
|
|||
|
|
@ -6,12 +6,10 @@
|
|||
|
||||
#include "parser/Parser.hpp"
|
||||
|
||||
using namespace obj;
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
using namespace BCgen;
|
||||
|
||||
void obj::BCgen::Genereate(ByteCode& out, StatementScope* body) {
|
||||
void obj::Generate(ByteCode& out, StatementScope* body) {
|
||||
auto root = FunctionDefinition();
|
||||
|
||||
root.inst(Instruction(OpCode::SCOPE_IN));
|
||||
|
|
@ -26,18 +24,18 @@ void obj::BCgen::Genereate(ByteCode& out, StatementScope* body) {
|
|||
}
|
||||
|
||||
ConstObject* FunctionDefinition::defineLocal(const std::string& id) {
|
||||
auto idx = mLocals.presents(id);
|
||||
// auto idx = mLocals.presents(id);
|
||||
// RelAssert(!idx && "Local Redefinition");
|
||||
auto const_str_id = mConstants.get(id);
|
||||
mLocals.put(id, const_str_id);
|
||||
return const_str_id;
|
||||
}
|
||||
|
||||
FunctionDefinition::FunctionDefinition(const std::string& function_id, tp::Buffer<std::string> args, FunctionDefinition* prnt) {
|
||||
FunctionDefinition::FunctionDefinition(const std::string& function_id, const Buffer<std::string>& args, FunctionDefinition*) {
|
||||
mFunctionId = function_id;
|
||||
inst(Instruction(OpCode::SAVE_ARGS, args.size(), 1));
|
||||
inst(Instruction(OpCode::SAVE_ARGS, (alni) args.size(), 1));
|
||||
for (auto id : args) {
|
||||
ASSERT(!mLocals.presents(id.data()) && "Argument Redefinition");
|
||||
ASSERT(!mLocals.presents(id.data()) && "Argument Redefinition")
|
||||
auto const_data = mConstants.get(id.data());
|
||||
mArgsOrder.pushBack(const_data);
|
||||
mLocals.put(id.data(), const_data);
|
||||
|
|
@ -124,7 +122,7 @@ void FunctionDefinition::EvalStatement(Statement* stm) {
|
|||
|
||||
// define method as local
|
||||
auto idx = mLocals.presents(func.mFunctionId);
|
||||
ASSERT(!idx && "Local Redefinition with function name");
|
||||
ASSERT(!idx && "Local Redefinition with function name")
|
||||
mLocals.put(func.mFunctionId, mConstants.get(func.mFunctionId));
|
||||
|
||||
// create and register const func object
|
||||
|
|
@ -152,7 +150,7 @@ void FunctionDefinition::EvalStatement(Statement* stm) {
|
|||
|
||||
// define method as local
|
||||
auto idx = mLocals.presents(func.mFunctionId);
|
||||
ASSERT(!idx && "Local Redefinition with function name");
|
||||
ASSERT(!idx && "Local Redefinition with function name")
|
||||
mLocals.put(func.mFunctionId, mConstants.get(func.mFunctionId));
|
||||
|
||||
// create and register const func object
|
||||
|
|
@ -164,7 +162,7 @@ void FunctionDefinition::EvalStatement(Statement* stm) {
|
|||
// check for return statements
|
||||
ASSERT(
|
||||
child_stm.data()->mType != Statement::Type::RET && "return statements are not allowed in class definition"
|
||||
);
|
||||
)
|
||||
func.EvalStatement(child_stm.data());
|
||||
}
|
||||
// create one last instruction - constructing class from function execution state
|
||||
|
|
@ -280,10 +278,10 @@ void FunctionDefinition::EvalExpr(Expression* expr) {
|
|||
}
|
||||
case Expression::Type::ARITHMETICS:
|
||||
{
|
||||
auto ariphm = (ExpressionArithmetics*) expr;
|
||||
EvalExpr(ariphm->mRight);
|
||||
EvalExpr(ariphm->mLeft);
|
||||
inst(Instruction(ariphm->mOpType));
|
||||
auto arithmeticExpression = (ExpressionArithmetics*) expr;
|
||||
EvalExpr(arithmeticExpression->mRight);
|
||||
EvalExpr(arithmeticExpression->mLeft);
|
||||
inst(Instruction(arithmeticExpression->mOpType));
|
||||
break;
|
||||
}
|
||||
case Expression::Type::NEW:
|
||||
|
|
@ -302,29 +300,29 @@ void FunctionDefinition::EvalExpr(Expression* expr) {
|
|||
}
|
||||
case Expression::Type::CONST_EXPR:
|
||||
{
|
||||
auto constobj = (ExpressionConst*) expr;
|
||||
switch (constobj->mConstType) {
|
||||
auto constObject = (ExpressionConst*) expr;
|
||||
switch (constObject->mConstType) {
|
||||
case ExpressionConst::STR:
|
||||
{
|
||||
inst(Instruction(OpCode::LOAD_CONST, mConstants.get(constobj->str)));
|
||||
inst(Instruction(OpCode::LOAD_CONST, mConstants.get(constObject->str)));
|
||||
break;
|
||||
}
|
||||
case ExpressionConst::INT:
|
||||
{
|
||||
inst(Instruction(OpCode::LOAD_CONST, mConstants.get(constobj->integer)));
|
||||
inst(Instruction(OpCode::LOAD_CONST, mConstants.get(constObject->integer)));
|
||||
break;
|
||||
}
|
||||
case ExpressionConst::FLT:
|
||||
{
|
||||
inst(Instruction(OpCode::LOAD_CONST, mConstants.get(constobj->floating)));
|
||||
inst(Instruction(OpCode::LOAD_CONST, mConstants.get(constObject->floating)));
|
||||
break;
|
||||
}
|
||||
case ExpressionConst::BOOL:
|
||||
{
|
||||
inst(Instruction(OpCode::LOAD_CONST, mConstants.get(constobj->boolean)));
|
||||
inst(Instruction(OpCode::LOAD_CONST, mConstants.get(constObject->boolean)));
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Expression::Type::CHILD:
|
||||
|
|
@ -343,7 +341,7 @@ void FunctionDefinition::EvalExpr(Expression* expr) {
|
|||
case Expression::Type::CALL:
|
||||
{
|
||||
auto call = (ExpressionCall*) expr;
|
||||
inst(Instruction(OpCode::PUSH_ARGS, call->mArgs->mItems.size(), 1));
|
||||
inst(Instruction(OpCode::PUSH_ARGS, (alni) call->mArgs->mItems.size(), 1));
|
||||
for (auto arg : call->mArgs->mItems) {
|
||||
EvalExpr(arg.data());
|
||||
}
|
||||
|
|
@ -356,13 +354,13 @@ void FunctionDefinition::EvalExpr(Expression* expr) {
|
|||
}
|
||||
}
|
||||
|
||||
tp::alni instSize(const Instruction& inst) {
|
||||
alni instSize(const Instruction& inst) {
|
||||
switch (inst.mInstType) {
|
||||
case Instruction::InstType::JUMP:
|
||||
case Instruction::InstType::JUMP_IF_NOT:
|
||||
case Instruction::InstType::JUMP_IF:
|
||||
{
|
||||
// 2 bytes for offset 1 byte for instrtuction
|
||||
// 2 bytes for offset 1 byte for instruction
|
||||
return 3;
|
||||
}
|
||||
case Instruction::InstType::PURE_CONST:
|
||||
|
|
@ -371,7 +369,7 @@ tp::alni instSize(const Instruction& inst) {
|
|||
}
|
||||
case Instruction::InstType::EXEC:
|
||||
{
|
||||
tp::alni out = 1;
|
||||
alni out = 1;
|
||||
switch (inst.mArgType) {
|
||||
case Instruction::ArgType::PARAM:
|
||||
{
|
||||
|
|
@ -392,7 +390,7 @@ tp::alni instSize(const Instruction& inst) {
|
|||
}
|
||||
default:
|
||||
{
|
||||
ASSERT(0);
|
||||
ASSERT(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -402,30 +400,30 @@ tp::alni instSize(const Instruction& inst) {
|
|||
}
|
||||
default:
|
||||
{
|
||||
ASSERT(0);
|
||||
ASSERT(0)
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(0);
|
||||
ASSERT(0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void writeConst(ByteCode& out, tp::alni& idx, tp::uint2 data) {
|
||||
for (auto byte : tp::Range(sizeof(tp::uint2))) {
|
||||
out.mInstructions[idx] = OpCode((tp::int1)(data >> byte * 8));
|
||||
void writeConst(ByteCode& out, alni& idx, uint2 data) {
|
||||
for (auto byte : Range(sizeof(uint2))) {
|
||||
out.mInstructions[idx] = OpCode((int1)(data >> byte * 8));
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
void writeParam(ByteCode& out, tp::alni& idx, tp::int1* data, tp::alni size) {
|
||||
for (auto byte : tp::Range(size)) {
|
||||
void writeParam(ByteCode& out, alni& idx, const int1* data, alni size) {
|
||||
for (auto byte : Range(size)) {
|
||||
out.mInstructions[idx] = OpCode(data[byte]);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
tp::alni calcOffset(tp::List<Instruction>::Node* jump_inst, Instruction* to) {
|
||||
tp::alni offset = 0;
|
||||
alni calcOffset(List<Instruction>::Node* jump_inst, Instruction* to) {
|
||||
alni offset = 0;
|
||||
bool reversed = jump_inst->data.mInstIdx > to->mInstIdx;
|
||||
auto iter_node = reversed ? jump_inst : jump_inst->next;
|
||||
while (&iter_node->data != to) {
|
||||
|
|
@ -445,13 +443,13 @@ void FunctionDefinition::generateByteCode(ByteCode& out) {
|
|||
|
||||
mConstants.save(out.mConstants);
|
||||
|
||||
tp::alni inst_len = 0;
|
||||
alni inst_len = 0;
|
||||
for (auto inst_iter : mInstructions) {
|
||||
inst_len += instSize(inst_iter.data());
|
||||
}
|
||||
out.mInstructions.reserve(inst_len);
|
||||
|
||||
tp::alni idx = 0;
|
||||
alni idx = 0;
|
||||
for (auto inst_iter : mInstructions) {
|
||||
auto inst = inst_iter.data();
|
||||
|
||||
|
|
@ -460,7 +458,7 @@ void FunctionDefinition::generateByteCode(ByteCode& out) {
|
|||
case Instruction::InstType::JUMP_IF_NOT:
|
||||
case Instruction::InstType::JUMP:
|
||||
{
|
||||
tp::alni offset = calcOffset(inst_iter.node(), inst.mInstTarget);
|
||||
alni offset = calcOffset(inst_iter.node(), inst.mInstTarget);
|
||||
|
||||
if (offset == 0) {
|
||||
out.mInstructions[idx] = OpCode::NONE;
|
||||
|
|
@ -490,14 +488,14 @@ void FunctionDefinition::generateByteCode(ByteCode& out) {
|
|||
|
||||
idx++;
|
||||
|
||||
tp::alni offset_mod = abs(offset);
|
||||
tp::uint2 offset_param = (tp::uint2) offset_mod;
|
||||
writeParam(out, idx, (tp::int1*) &offset_param, 2);
|
||||
alni offset_mod = abs(offset);
|
||||
auto offset_param = (uint2) offset_mod;
|
||||
writeParam(out, idx, (int1*) &offset_param, 2);
|
||||
break;
|
||||
}
|
||||
case Instruction::InstType::PURE_CONST:
|
||||
{
|
||||
writeConst(out, idx, (tp::uint2) inst.mConstData->mConstIdx);
|
||||
writeConst(out, idx, (uint2) inst.mConstData->mConstIdx);
|
||||
break;
|
||||
}
|
||||
case Instruction::InstType::EXEC:
|
||||
|
|
@ -507,14 +505,14 @@ void FunctionDefinition::generateByteCode(ByteCode& out) {
|
|||
switch (inst.mArgType) {
|
||||
case Instruction::ArgType::PARAM:
|
||||
{
|
||||
writeParam(out, idx, (tp::int1*) &inst.mParam, inst.mParamBytes);
|
||||
writeParam(out, idx, (int1*) &inst.mParam, inst.mParamBytes);
|
||||
break;
|
||||
}
|
||||
case Instruction::ArgType::CONST_ARG:
|
||||
{
|
||||
writeConst(out, idx, (tp::uint2) inst.mConstData->mConstIdx);
|
||||
writeConst(out, idx, (uint2) inst.mConstData->mConstIdx);
|
||||
if (inst.mConstData2) {
|
||||
writeConst(out, idx, (tp::uint2) inst.mConstData2->mConstIdx);
|
||||
writeConst(out, idx, (uint2) inst.mConstData2->mConstIdx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -524,14 +522,14 @@ void FunctionDefinition::generateByteCode(ByteCode& out) {
|
|||
}
|
||||
default:
|
||||
{
|
||||
ASSERT(0);
|
||||
ASSERT(0)
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ASSERT(0);
|
||||
ASSERT(0)
|
||||
}
|
||||
case Instruction::InstType::NONE:
|
||||
{
|
||||
|
|
@ -540,18 +538,18 @@ void FunctionDefinition::generateByteCode(ByteCode& out) {
|
|||
}
|
||||
}
|
||||
|
||||
tp::List<Instruction>::Node* FunctionDefinition::inst(Instruction inst) {
|
||||
List<Instruction>::Node* FunctionDefinition::inst(Instruction inst) {
|
||||
mInstructions.pushBack(inst);
|
||||
auto out = &mInstructions.last()->data;
|
||||
out->mInstIdx = mInstructions.length() - 1;
|
||||
out->mInstIdx = (alni) mInstructions.length() - 1;
|
||||
return mInstructions.last();
|
||||
}
|
||||
|
||||
void obj::BCgen::init() {}
|
||||
void obj::initialize() {}
|
||||
|
||||
void obj::BCgen::deinit() {}
|
||||
void obj::finalize() {}
|
||||
|
||||
bool obj::BCgen::Compile(obj::MethodObject* method) {
|
||||
bool obj::Compile(obj::MethodObject* method) {
|
||||
|
||||
Parser parser;
|
||||
|
||||
|
|
@ -563,7 +561,7 @@ bool obj::BCgen::Compile(obj::MethodObject* method) {
|
|||
return false;
|
||||
}
|
||||
|
||||
BCgen::Genereate(method->mScript->mBytecode, res.scope);
|
||||
Generate(method->mScript->mBytecode, res.scope);
|
||||
|
||||
delete res.scope;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
|
||||
#include "compiler/Instructions.hpp"
|
||||
|
||||
using namespace obj;
|
||||
using namespace tp;
|
||||
using namespace BCgen;
|
||||
using namespace obj;
|
||||
|
||||
Instruction::Instruction(OpCode op) :
|
||||
mOp(op),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
#include "compiler/Statements.hpp"
|
||||
#include <utility>
|
||||
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
using namespace BCgen;
|
||||
|
||||
StatementFuncDef::StatementFuncDef(const std::string& function_id) :
|
||||
Statement(Type::DEF_FUNC) {
|
||||
|
|
@ -10,8 +11,8 @@ StatementFuncDef::StatementFuncDef(const std::string& function_id) :
|
|||
|
||||
StatementFuncDef::~StatementFuncDef() { delete mStatements; }
|
||||
|
||||
StatementLocalDef::StatementLocalDef(const std::string& id, Expression* value) :
|
||||
mLocalId(id),
|
||||
StatementLocalDef::StatementLocalDef(std::string id, Expression* value) :
|
||||
mLocalId(std::move(id)),
|
||||
Statement(Type::DEF_LOCAL) {
|
||||
|
||||
if (value->mType == Expression::Type::CONST_EXPR) {
|
||||
|
|
@ -53,7 +54,7 @@ StatementPrint::StatementPrint(Expression* target) :
|
|||
|
||||
StatementPrint::~StatementPrint() { delete mTarget; }
|
||||
|
||||
StatementScope::StatementScope(tp::InitialierList<Statement*> statements, bool aPushToScopeStack) :
|
||||
StatementScope::StatementScope(InitialierList<Statement*> statements, bool aPushToScopeStack) :
|
||||
Statement(Type::SCOPE) {
|
||||
mStatements = statements;
|
||||
mPushToScopeStack = aPushToScopeStack;
|
||||
|
|
|
|||
|
|
@ -1,241 +1,239 @@
|
|||
|
||||
|
||||
#include "core/Object.hpp"
|
||||
|
||||
#include "primitives/ClassObject.hpp"
|
||||
#include "primitives/MethodObject.hpp"
|
||||
#include "primitives/NullObject.hpp"
|
||||
|
||||
#include "compiler/Functions.hpp"
|
||||
#include "interpreter/Interpreter.hpp"
|
||||
|
||||
namespace obj {
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
void save_string(ArchiverOut& file, const std::string& string) {
|
||||
file << string.size();
|
||||
file.writeBytes(string.c_str(), string.size());
|
||||
}
|
||||
void obj::save_string(ArchiverOut& file, const std::string& string) {
|
||||
file << string.size();
|
||||
file.writeBytes(string.c_str(), string.size());
|
||||
}
|
||||
|
||||
tp::ualni save_string_size(const std::string& string) {
|
||||
return string.size() + sizeof(string.size());
|
||||
}
|
||||
ualni obj::save_string_size(const std::string& string) {
|
||||
return string.size() + sizeof(string.size());
|
||||
}
|
||||
|
||||
void load_string(ArchiverIn& file, std::string& out) {
|
||||
typeof(out.size()) size;
|
||||
file >> size;
|
||||
auto buff = new char[size + 1];
|
||||
file.readBytes(buff, size);
|
||||
buff[size] = 0;
|
||||
out = buff;
|
||||
delete[] buff;
|
||||
}
|
||||
void obj::load_string(ArchiverIn& file, std::string& out) {
|
||||
typeof(out.size()) size;
|
||||
file >> size;
|
||||
auto buff = new char[size + 1];
|
||||
file.readBytes(buff, size);
|
||||
buff[size] = 0;
|
||||
out = buff;
|
||||
delete[] buff;
|
||||
}
|
||||
|
||||
Object* ObjectMemAllocate(const ObjectType* type);
|
||||
void ObjectMemDeallocate(Object* in);
|
||||
Object* ObjectMemAllocate(const ObjectType* type);
|
||||
void ObjectMemDeallocate(Object* in);
|
||||
|
||||
objects_api* NDO = nullptr;
|
||||
objects_api* obj::NDO = nullptr;
|
||||
|
||||
void hierarchy_copy(Object* self, const Object* in, const ObjectType* type);
|
||||
void hierarchy_construct(Object* self, const ObjectType* type);
|
||||
void hierarchy_copy(Object* self, const Object* in, const ObjectType* type);
|
||||
void hierarchy_construct(Object* self, const ObjectType* type);
|
||||
|
||||
objects_api::objects_api() {
|
||||
tp::memSetVal(sl_callbacks, SAVE_LOAD_MAX_CALLBACK_SLOTS * sizeof(save_load_callbacks*), 0);
|
||||
interp = new Interpreter();
|
||||
}
|
||||
objects_api::objects_api() {
|
||||
memSetVal(sl_callbacks, SAVE_LOAD_MAX_CALLBACK_SLOTS * sizeof(save_load_callbacks*), 0);
|
||||
interp = new Interpreter();
|
||||
}
|
||||
|
||||
objects_api::~objects_api() { delete interp; }
|
||||
objects_api::~objects_api() { delete interp; }
|
||||
|
||||
void objects_api::define(ObjectType* type) {
|
||||
MODULE_SANITY_CHECK(gModuleObjects);
|
||||
void objects_api::define(ObjectType* type) {
|
||||
MODULE_SANITY_CHECK(gModuleObjects)
|
||||
|
||||
DEBUG_ASSERT(NDO && "using uninitialize objects api");
|
||||
DEBUG_ASSERT(!types.presents(type->name) && "Type Redefinition");
|
||||
types.put(type->name, type);
|
||||
DEBUG_ASSERT(NDO && "using uninitialized objects api")
|
||||
DEBUG_ASSERT(!types.presents(type->name) && "Type Redefinition")
|
||||
types.put(type->name, type);
|
||||
|
||||
type->type_methods.init();
|
||||
}
|
||||
type->type_methods.init();
|
||||
}
|
||||
|
||||
Object* objects_api::create(const std::string& name) {
|
||||
MODULE_SANITY_CHECK(gModuleObjects);
|
||||
Object* objects_api::create(const std::string& name) {
|
||||
MODULE_SANITY_CHECK(gModuleObjects)
|
||||
|
||||
const ObjectType* type = types.get(name);
|
||||
const ObjectType* type = types.get(name);
|
||||
|
||||
Object* obj_instance = ObjectMemAllocate(type);
|
||||
Object* obj_instance = ObjectMemAllocate(type);
|
||||
|
||||
if (!obj_instance) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
hierarchy_construct(obj_instance, obj_instance->type);
|
||||
|
||||
setrefc(obj_instance, 0);
|
||||
|
||||
NDO_CASTV(ClassObject, obj_instance, classobj);
|
||||
if (classobj) {
|
||||
auto idx = classobj->members->presents("__init__");
|
||||
DEBUG_ASSERT(idx);
|
||||
if (idx) {
|
||||
auto constructor_obj = classobj->members->getSlotVal(idx);
|
||||
NDO_CASTV(MethodObject, constructor_obj, constructor_method);
|
||||
if (constructor_method) {
|
||||
interp->execAll(constructor_method, classobj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj_instance;
|
||||
}
|
||||
|
||||
Object* objects_api::copy(Object* self, const Object* in) {
|
||||
if (self->type != in->type) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
hierarchy_copy(self, in, self->type);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
bool objects_api::compare(Object* first, Object* second) {
|
||||
if (first->type == second->type) {
|
||||
if (first->type->comparison) {
|
||||
return first->type->comparison(first, second);
|
||||
}
|
||||
|
||||
// raw data comparison
|
||||
return tp::memCompare(first, second, first->type->size) == 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Object* objects_api::instatiate(Object* in) {
|
||||
obj::Object* obj = NDO->create(in->type->name);
|
||||
NDO->copy(obj, in);
|
||||
return obj;
|
||||
}
|
||||
|
||||
void objects_api::set(Object* self, tp::alni val) {
|
||||
if (self->type->convesions && self->type->convesions->from_int) {
|
||||
self->type->convesions->from_int(self, val);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void objects_api::set(Object* self, tp::alnf val) {
|
||||
if (self->type->convesions && self->type->convesions->from_float) {
|
||||
self->type->convesions->from_float(self, val);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void objects_api::set(Object* self, const std::string& val) {
|
||||
if (self->type->convesions && self->type->convesions->from_string) {
|
||||
self->type->convesions->from_string(self, val);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
tp::alni objects_api::toInt(Object* self) {
|
||||
DEBUG_ASSERT(self->type->convesions && self->type->convesions->to_int);
|
||||
return self->type->convesions->to_int(self);
|
||||
}
|
||||
|
||||
tp::alnf objects_api::toFloat(Object* self) {
|
||||
DEBUG_ASSERT(self->type->convesions && self->type->convesions->to_float);
|
||||
return self->type->convesions->to_float(self);
|
||||
}
|
||||
|
||||
bool objects_api::toBool(Object* self) {
|
||||
if (self->type->convesions && self->type->convesions->to_int) {
|
||||
return (bool) self->type->convesions->to_int(self);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string objects_api::toString(Object* self) {
|
||||
DEBUG_ASSERT(self->type->convesions && self->type->convesions->to_string);
|
||||
return self->type->convesions->to_string(self);
|
||||
}
|
||||
|
||||
void objects_api::destroy(Object* in) {
|
||||
|
||||
if (!in) {
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectMemHead* mh = NDO_MEMH_FROM_NDO(in);
|
||||
if (mh->refc > 1) {
|
||||
mh->refc--;
|
||||
return;
|
||||
}
|
||||
|
||||
NDO_CASTV(ClassObject, in, classobj);
|
||||
if (classobj) {
|
||||
auto idx = classobj->members->presents("__del__");
|
||||
DEBUG_ASSERT(idx);
|
||||
if (idx) {
|
||||
auto constructor_obj = classobj->members->getSlotVal(idx);
|
||||
NDO_CASTV(MethodObject, constructor_obj, constructor_method);
|
||||
if (constructor_method) {
|
||||
interp->execAll(constructor_method, classobj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const ObjectType* iter = in->type; iter; iter = iter->base) {
|
||||
if (iter->destructor) {
|
||||
iter->destructor(in);
|
||||
}
|
||||
}
|
||||
|
||||
ObjectMemDeallocate(in);
|
||||
}
|
||||
|
||||
tp::halni objects_api::getrefc(Object* in) {
|
||||
ObjectMemHead* mh = NDO_MEMH_FROM_NDO(in);
|
||||
return (tp::halni) mh->refc;
|
||||
}
|
||||
|
||||
void objects_api::refinc(Object* in) {
|
||||
ObjectMemHead* mh = NDO_MEMH_FROM_NDO(in);
|
||||
mh->refc++;
|
||||
}
|
||||
|
||||
void objects_api::setrefc(Object* in, tp::halni refc) {
|
||||
ObjectMemHead* mh = NDO_MEMH_FROM_NDO(in);
|
||||
mh->refc = refc;
|
||||
}
|
||||
|
||||
|
||||
void hierarchy_copy(Object* self, const Object* in, const ObjectType* type) {
|
||||
if (type->base) {
|
||||
hierarchy_copy(self, in, type->base);
|
||||
}
|
||||
|
||||
if (type->copy) {
|
||||
type->copy(self, in);
|
||||
}
|
||||
}
|
||||
|
||||
void hierarchy_construct(Object* self, const ObjectType* type) {
|
||||
if (type->base) {
|
||||
hierarchy_construct(self, type->base);
|
||||
}
|
||||
|
||||
if (type->constructor) {
|
||||
type->constructor(self);
|
||||
}
|
||||
}
|
||||
|
||||
Object* ndo_cast(const Object* in, const ObjectType* to_type) {
|
||||
const ObjectType* typeiter = in->type;
|
||||
while (typeiter) {
|
||||
if (typeiter == to_type) {
|
||||
return (Object*) in;
|
||||
}
|
||||
typeiter = typeiter->base;
|
||||
}
|
||||
if (!obj_instance) {
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
hierarchy_construct(obj_instance, obj_instance->type);
|
||||
|
||||
setReferenceCount(obj_instance, 0);
|
||||
|
||||
NDO_CASTV(ClassObject, obj_instance, classobj);
|
||||
|
||||
if (classobj) {
|
||||
auto idx = classobj->members->presents("__init__");
|
||||
DEBUG_ASSERT(idx)
|
||||
if (idx) {
|
||||
auto constructor_obj = classobj->members->getSlotVal(idx);
|
||||
NDO_CASTV(MethodObject, constructor_obj, constructor_method);
|
||||
if (constructor_method) {
|
||||
interp->execAll(constructor_method, classobj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj_instance;
|
||||
}
|
||||
|
||||
Object* objects_api::copy(Object* self, const Object* in) {
|
||||
if (self->type != in->type) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
hierarchy_copy(self, in, self->type);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
bool objects_api::compare(Object* first, Object* second) {
|
||||
if (first->type == second->type) {
|
||||
if (first->type->comparison) {
|
||||
return first->type->comparison(first, second);
|
||||
}
|
||||
|
||||
// raw data comparison
|
||||
return memCompare(first, second, first->type->size) == 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Object* objects_api::instantiate(Object* in) {
|
||||
obj::Object* obj = NDO->create(in->type->name);
|
||||
NDO->copy(obj, in);
|
||||
return obj;
|
||||
}
|
||||
|
||||
void objects_api::set(Object* self, alni val) {
|
||||
if (self->type->convesions && self->type->convesions->from_int) {
|
||||
self->type->convesions->from_int(self, val);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void objects_api::set(Object* self, alnf val) {
|
||||
if (self->type->convesions && self->type->convesions->from_float) {
|
||||
self->type->convesions->from_float(self, val);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void objects_api::set(Object* self, const std::string& val) {
|
||||
if (self->type->convesions && self->type->convesions->from_string) {
|
||||
self->type->convesions->from_string(self, val);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
alni objects_api::toInt(Object* self) {
|
||||
DEBUG_ASSERT(self->type->convesions && self->type->convesions->to_int)
|
||||
return self->type->convesions->to_int(self);
|
||||
}
|
||||
|
||||
alnf objects_api::toFloat(Object* self) {
|
||||
DEBUG_ASSERT(self->type->convesions && self->type->convesions->to_float)
|
||||
return self->type->convesions->to_float(self);
|
||||
}
|
||||
|
||||
bool objects_api::toBool(Object* self) {
|
||||
if (self->type->convesions && self->type->convesions->to_int) {
|
||||
return (bool) self->type->convesions->to_int(self);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string objects_api::toString(Object* self) {
|
||||
DEBUG_ASSERT(self->type->convesions && self->type->convesions->to_string)
|
||||
return self->type->convesions->to_string(self);
|
||||
}
|
||||
|
||||
void objects_api::destroy(Object* in) const {
|
||||
|
||||
if (!in) {
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectMemHead* mh = NDO_MEMH_FROM_NDO(in);
|
||||
if (mh->refc > 1) {
|
||||
mh->refc--;
|
||||
return;
|
||||
}
|
||||
|
||||
NDO_CASTV(ClassObject, in, classobj);
|
||||
if (classobj) {
|
||||
auto idx = classobj->members->presents("__del__");
|
||||
DEBUG_ASSERT(idx)
|
||||
if (idx) {
|
||||
auto constructor_obj = classobj->members->getSlotVal(idx);
|
||||
NDO_CASTV(MethodObject, constructor_obj, constructor_method);
|
||||
if (constructor_method) {
|
||||
interp->execAll(constructor_method, classobj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const ObjectType* iter = in->type; iter; iter = iter->base) {
|
||||
if (iter->destructor) {
|
||||
iter->destructor(in);
|
||||
}
|
||||
}
|
||||
|
||||
ObjectMemDeallocate(in);
|
||||
}
|
||||
|
||||
halni objects_api::getReferenceCount(Object* in) {
|
||||
ObjectMemHead* mh = NDO_MEMH_FROM_NDO(in);
|
||||
return (halni) mh->refc;
|
||||
}
|
||||
|
||||
void objects_api::increaseReferenceCount(Object* in) {
|
||||
ObjectMemHead* mh = NDO_MEMH_FROM_NDO(in);
|
||||
mh->refc++;
|
||||
}
|
||||
|
||||
void objects_api::setReferenceCount(Object* in, halni count) {
|
||||
ObjectMemHead* mh = NDO_MEMH_FROM_NDO(in);
|
||||
mh->refc = count;
|
||||
}
|
||||
|
||||
|
||||
void hierarchy_copy(Object* self, const Object* in, const ObjectType* type) {
|
||||
if (type->base) {
|
||||
hierarchy_copy(self, in, type->base);
|
||||
}
|
||||
|
||||
if (type->copy) {
|
||||
type->copy(self, in);
|
||||
}
|
||||
}
|
||||
|
||||
void hierarchy_construct(Object* self, const ObjectType* type) {
|
||||
if (type->base) {
|
||||
hierarchy_construct(self, type->base);
|
||||
}
|
||||
|
||||
if (type->constructor) {
|
||||
type->constructor(self);
|
||||
}
|
||||
}
|
||||
|
||||
Object* obj::ndo_cast(const Object* in, const ObjectType* to_type) {
|
||||
const ObjectType* typeIter = in->type;
|
||||
while (typeIter) {
|
||||
if (typeIter == to_type) {
|
||||
return (Object*) in;
|
||||
}
|
||||
typeIter = typeIter->base;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,434 +6,434 @@
|
|||
|
||||
#include <malloc.h>
|
||||
|
||||
namespace obj {
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
ObjectMemHead* bottom = nullptr;
|
||||
tp::ualni count = 0;
|
||||
ObjectMemHead* bottom = nullptr;
|
||||
ualni count = 0;
|
||||
|
||||
struct ObjectsFileHeader {
|
||||
char name[10] = { 0 };
|
||||
char version[10] = { 0 };
|
||||
struct ObjectsFileHeader {
|
||||
char name[10] = { 0 };
|
||||
char version[10] = { 0 };
|
||||
|
||||
ObjectsFileHeader(bool default_val = true) {
|
||||
if (default_val) {
|
||||
tp::memCopy(&name, "objects", 8);
|
||||
tp::memCopy(&version, "0", 2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Object* ObjectMemAllocate(const ObjectType* type) {
|
||||
ObjectMemHead* memh = (ObjectMemHead*) malloc(type->size + sizeof(ObjectMemHead));
|
||||
if (!memh) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
memh->down = nullptr;
|
||||
memh->flags = 0;
|
||||
|
||||
memh->refc = (tp::alni) 1;
|
||||
|
||||
if (bottom) {
|
||||
bottom->down = memh;
|
||||
}
|
||||
|
||||
memh->up = bottom;
|
||||
bottom = memh;
|
||||
|
||||
count++;
|
||||
|
||||
NDO_FROM_MEMH(memh)->type = type;
|
||||
return NDO_FROM_MEMH(memh);
|
||||
}
|
||||
|
||||
void ObjectMemDeallocate(Object* in) {
|
||||
ObjectMemHead* memh = ((ObjectMemHead*) in) - 1;
|
||||
|
||||
if (memh->up) {
|
||||
memh->up->down = memh->down;
|
||||
}
|
||||
|
||||
if (memh->down) {
|
||||
memh->down->up = memh->up;
|
||||
} else {
|
||||
bottom = memh->up;
|
||||
}
|
||||
|
||||
free(memh);
|
||||
|
||||
count--;
|
||||
}
|
||||
|
||||
void logTypeData(const ObjectType* type) {
|
||||
printf("type - %s\n", type->name);
|
||||
if (type->base) {
|
||||
printf("Based on ");
|
||||
logTypeData(type->base);
|
||||
ObjectsFileHeader(bool default_val = true) {
|
||||
if (default_val) {
|
||||
memCopy(&name, "objects", 8);
|
||||
memCopy(&version, "0", 2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
tp::ualni getObjCount() { return count; }
|
||||
|
||||
void assertNoLeaks() {
|
||||
if (bottom) {
|
||||
printf("ERROR : not all objects are destroyed\n");
|
||||
tp::ualni idx = 0;
|
||||
for (ObjectMemHead* memh = bottom; memh; memh = memh->up) {
|
||||
printf(" ===== Object - %i. Ref count - %i ===== \n", idx, memh->refc);
|
||||
logTypeData(NDO_FROM_MEMH(memh)->type);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
Object* ObjectMemAllocate(const ObjectType* type) {
|
||||
ObjectMemHead* memh = (ObjectMemHead*) malloc(type->size + sizeof(ObjectMemHead));
|
||||
if (!memh) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct ObjectFileHead {
|
||||
Object* load_head_adress = 0;
|
||||
tp::halni refc = 0;
|
||||
};
|
||||
memh->down = nullptr;
|
||||
memh->flags = 0;
|
||||
|
||||
tp::int1* loaded_file = nullptr;
|
||||
memh->refc = (alni) 1;
|
||||
|
||||
void objects_api::clear_object_flags() {
|
||||
// clear all object flags
|
||||
for (ObjectMemHead* iter = bottom; iter; iter = iter->up) {
|
||||
iter->flags = -1;
|
||||
}
|
||||
if (bottom) {
|
||||
bottom->down = memh;
|
||||
}
|
||||
|
||||
tp::alni& getObjectFlags(Object* in) { return NDO_MEMH_FROM_NDO(in)->flags; }
|
||||
memh->up = bottom;
|
||||
bottom = memh;
|
||||
|
||||
tp::alni objsize_ram_util(Object* self, const ObjectType* type) {
|
||||
tp::alni out = 0;
|
||||
count++;
|
||||
|
||||
NDO_FROM_MEMH(memh)->type = type;
|
||||
return NDO_FROM_MEMH(memh);
|
||||
}
|
||||
|
||||
void ObjectMemDeallocate(Object* in) {
|
||||
ObjectMemHead* memh = ((ObjectMemHead*) in) - 1;
|
||||
|
||||
if (memh->up) {
|
||||
memh->up->down = memh->down;
|
||||
}
|
||||
|
||||
if (memh->down) {
|
||||
memh->down->up = memh->up;
|
||||
} else {
|
||||
bottom = memh->up;
|
||||
}
|
||||
|
||||
free(memh);
|
||||
|
||||
count--;
|
||||
}
|
||||
|
||||
void obj::logTypeData(const ObjectType* type) {
|
||||
printf("type - %s\n", type->name);
|
||||
if (type->base) {
|
||||
printf("Based on ");
|
||||
logTypeData(type->base);
|
||||
}
|
||||
}
|
||||
|
||||
ualni obj::getObjCount() { return count; }
|
||||
|
||||
void obj::assertNoLeaks() {
|
||||
if (bottom) {
|
||||
printf("ERROR : not all objects are destroyed\n");
|
||||
ualni idx = 0;
|
||||
for (ObjectMemHead* memh = bottom; memh; memh = memh->up) {
|
||||
printf(" ===== Object - %i. Ref count - %i ===== \n", idx, memh->refc);
|
||||
logTypeData(NDO_FROM_MEMH(memh)->type);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ObjectFileHead {
|
||||
Object* load_head_adress = 0;
|
||||
halni refc = 0;
|
||||
};
|
||||
|
||||
int1* loaded_file = nullptr;
|
||||
|
||||
void objects_api::clear_object_flags() {
|
||||
// clear all object flags
|
||||
for (ObjectMemHead* iter = bottom; iter; iter = iter->up) {
|
||||
iter->flags = -1;
|
||||
}
|
||||
}
|
||||
|
||||
alni& getObjectFlags(Object* in) { return NDO_MEMH_FROM_NDO(in)->flags; }
|
||||
|
||||
alni objsize_ram_util(Object* self, const ObjectType* type) {
|
||||
alni out = 0;
|
||||
|
||||
if (type->allocated_size) {
|
||||
out += type->allocated_size(self);
|
||||
} else {
|
||||
out += type->size - sizeof(ObjectType*);
|
||||
}
|
||||
|
||||
if (type->base) {
|
||||
out += objsize_ram_util(self, type->base);
|
||||
} else {
|
||||
out += sizeof(ObjectType*);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
alni objects_api::objsize_ram(Object* self) { return objsize_ram_util(self, self->type); }
|
||||
|
||||
alni objects_api::objsize_ram_recursive_util(Object* self, const ObjectType* type, bool different_object) {
|
||||
alni out = 0;
|
||||
|
||||
if (different_object) {
|
||||
if (getObjectFlags(self) == 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
getObjectFlags(self) = 1;
|
||||
}
|
||||
|
||||
if (type->allocated_size_recursive) {
|
||||
out += type->allocated_size_recursive(self);
|
||||
} else {
|
||||
if (type->allocated_size) {
|
||||
out += type->allocated_size(self);
|
||||
} else {
|
||||
out += type->size - sizeof(ObjectType*);
|
||||
}
|
||||
|
||||
if (type->base) {
|
||||
out += objsize_ram_util(self, type->base);
|
||||
} else {
|
||||
out += sizeof(ObjectType*);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
tp::alni objects_api::objsize_ram(Object* self) { return objsize_ram_util(self, self->type); }
|
||||
if (type->base) {
|
||||
out += objsize_ram_recursive_util(self, type->base, false);
|
||||
} else {
|
||||
out += sizeof(ObjectType*);
|
||||
}
|
||||
|
||||
tp::alni objects_api::objsize_ram_recursive_util(Object* self, const ObjectType* type, bool different_object) {
|
||||
tp::alni out = 0;
|
||||
return out;
|
||||
}
|
||||
|
||||
if (different_object) {
|
||||
if (getObjectFlags(self) == 1) {
|
||||
return 0;
|
||||
}
|
||||
alni objects_api::objsize_ram_recursive(Object* self) {
|
||||
clear_object_flags();
|
||||
return objsize_ram_recursive_util(self, self->type);
|
||||
}
|
||||
|
||||
getObjectFlags(self) = 1;
|
||||
}
|
||||
alni objsize_file_util(Object* self, const ObjectType* type) {
|
||||
alni out = 0;
|
||||
|
||||
if (type->allocated_size_recursive) {
|
||||
out += type->allocated_size_recursive(self);
|
||||
} else {
|
||||
if (type->allocated_size) {
|
||||
out += type->allocated_size(self);
|
||||
} else {
|
||||
out += type->size - sizeof(ObjectType*);
|
||||
if (type->save_size) {
|
||||
out += type->save_size(self);
|
||||
}
|
||||
|
||||
if (type->base) {
|
||||
out += objsize_file_util(self, type->base);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
alni objects_api::objsize_file(Object* self) { return objsize_file_util(self, self->type); }
|
||||
|
||||
alni objsize_file_recursive_util(Object* self, const ObjectType* type) {
|
||||
alni out = 0;
|
||||
|
||||
getObjectFlags(self) = 1;
|
||||
|
||||
if (type->save_size) {
|
||||
out += type->save_size(self);
|
||||
}
|
||||
|
||||
if (type->childs_retrival) {
|
||||
Buffer<Object*> childs = type->childs_retrival(self);
|
||||
for (auto child : childs) {
|
||||
if (getObjectFlags(child.data()) != 1) {
|
||||
out += objsize_file_recursive_util(child.data(), child.data()->type);
|
||||
}
|
||||
}
|
||||
|
||||
if (type->base) {
|
||||
out += objsize_ram_recursive_util(self, type->base, false);
|
||||
} else {
|
||||
out += sizeof(ObjectType*);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
tp::alni objects_api::objsize_ram_recursive(Object* self) {
|
||||
clear_object_flags();
|
||||
return objsize_ram_recursive_util(self, self->type);
|
||||
if (type->base) {
|
||||
out += objsize_file_recursive_util(self, type->base);
|
||||
}
|
||||
|
||||
tp::alni objsize_file_util(Object* self, const ObjectType* type) {
|
||||
tp::alni out = 0;
|
||||
return out;
|
||||
}
|
||||
|
||||
if (type->save_size) {
|
||||
out += type->save_size(self);
|
||||
}
|
||||
alni objects_api::objsize_file_recursive(Object* self) {
|
||||
clear_object_flags();
|
||||
return objsize_file_recursive_util(self, self->type);
|
||||
}
|
||||
|
||||
if (type->base) {
|
||||
out += objsize_file_util(self, type->base);
|
||||
}
|
||||
return out;
|
||||
void object_recursive_save(ArchiverOut& ndf, Object* self, const ObjectType* type) {
|
||||
if (type->base) {
|
||||
object_recursive_save(ndf, self, type->base);
|
||||
}
|
||||
|
||||
tp::alni objects_api::objsize_file(Object* self) { return objsize_file_util(self, self->type); }
|
||||
// automatically offsets for parent type to write
|
||||
if (type->save) {
|
||||
type->save(self, ndf);
|
||||
}
|
||||
}
|
||||
|
||||
tp::alni objsize_file_recursive_util(Object* self, const ObjectType* type) {
|
||||
tp::alni out = 0;
|
||||
|
||||
getObjectFlags(self) = 1;
|
||||
|
||||
if (type->save_size) {
|
||||
out += type->save_size(self);
|
||||
}
|
||||
|
||||
if (type->childs_retrival) {
|
||||
tp::Buffer<Object*> childs = type->childs_retrival(self);
|
||||
for (auto child : childs) {
|
||||
if (getObjectFlags(child.data()) != 1) {
|
||||
out += objsize_file_recursive_util(child.data(), child.data()->type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type->base) {
|
||||
out += objsize_file_recursive_util(self, type->base);
|
||||
}
|
||||
|
||||
return out;
|
||||
alni objects_api::save(ArchiverOut& ndf, Object* in) {
|
||||
// if already saved return file_adress
|
||||
if (NDO_MEMH_FROM_NDO(in)->flags != -1) {
|
||||
return NDO_MEMH_FROM_NDO(in)->flags;
|
||||
}
|
||||
|
||||
tp::alni objects_api::objsize_file_recursive(Object* self) {
|
||||
clear_object_flags();
|
||||
return objsize_file_recursive_util(self, self->type);
|
||||
// save write adress for parent save function call
|
||||
alni tmp_adress = ndf.getAddress();
|
||||
|
||||
// save requested object to first available adress
|
||||
alni save_adress = ndf.getFreeAddress();
|
||||
|
||||
// save file_adress in memhead
|
||||
NDO_MEMH_FROM_NDO(in)->flags = save_adress;
|
||||
|
||||
// update write adress
|
||||
ndf.setAddress(save_adress);
|
||||
|
||||
// save file object header
|
||||
ObjectFileHead ofh = { 0, getReferenceCount(in) };
|
||||
ndf << ofh;
|
||||
|
||||
save_string(ndf, in->type->name);
|
||||
|
||||
// allocate for object file header
|
||||
ndf.setFreeAddress(ndf.getFreeAddress() + sizeof(ObjectFileHead) + save_string_size(in->type->name));
|
||||
|
||||
// calc max size needed for saving all hierarchy of types
|
||||
alni file_alloc_size = objsize_file_util(in, in->type);
|
||||
|
||||
// offes first available adress
|
||||
ndf.setFreeAddress(ndf.getFreeAddress() + file_alloc_size);
|
||||
|
||||
object_recursive_save(ndf, in, in->type);
|
||||
|
||||
// restore adress for parent save function
|
||||
ndf.setAddress(tmp_adress);
|
||||
|
||||
// return addres of saved object in file space
|
||||
return save_adress;
|
||||
}
|
||||
|
||||
void object_recursive_load(ArchiverIn& ndf, Object* out, const ObjectType* type) {
|
||||
if (type->base) {
|
||||
object_recursive_load(ndf, out, type->base);
|
||||
}
|
||||
|
||||
void object_recursive_save(ArchiverOut& ndf, Object* self, const ObjectType* type) {
|
||||
if (type->base) {
|
||||
object_recursive_save(ndf, self, type->base);
|
||||
}
|
||||
// automatically offsets for parent type to read
|
||||
if (type->load) {
|
||||
type->load(ndf, out);
|
||||
}
|
||||
}
|
||||
|
||||
// automatically offsets for parent type to write
|
||||
if (type->save) {
|
||||
type->save(self, ndf);
|
||||
Object* objects_api::load(ArchiverIn& ndf, alni file_adress) {
|
||||
// check if already saved
|
||||
if (((ObjectFileHead*) (loaded_file + file_adress))->load_head_adress) {
|
||||
return ((ObjectFileHead*) (loaded_file + file_adress))->load_head_adress;
|
||||
}
|
||||
|
||||
// save read address
|
||||
alni parent_file_adress = ndf.getAddress();
|
||||
|
||||
// set read address
|
||||
ndf.setAddress(file_adress);
|
||||
|
||||
ObjectFileHead ofh;
|
||||
ndf >> ofh;
|
||||
|
||||
std::string type_name;
|
||||
load_string(ndf, type_name);
|
||||
|
||||
const ObjectType* object_type = NDO->types.get(type_name);
|
||||
Object* out = ObjectMemAllocate(object_type);
|
||||
|
||||
if (!out) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
setReferenceCount(out, 0);
|
||||
|
||||
// check for null object
|
||||
if (out->type == &NullObject::TypeData) {
|
||||
ObjectMemDeallocate(out);
|
||||
out = NdoNull_globalInstance;
|
||||
}
|
||||
|
||||
// save heap adress in "loaded_file"
|
||||
((ObjectFileHead*) (loaded_file + file_adress))->load_head_adress = out;
|
||||
|
||||
// loads recursively
|
||||
object_recursive_load(ndf, out, object_type);
|
||||
|
||||
// restore read address for parent call to continue
|
||||
ndf.setAddress(parent_file_adress);
|
||||
|
||||
// return heap memory adress
|
||||
return out;
|
||||
}
|
||||
|
||||
bool objects_api::save(Object* in, const std::string& path, bool compressed) {
|
||||
ArchiverOut ndf(path.c_str());
|
||||
|
||||
if (!ndf.isOpened()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
clear_object_flags();
|
||||
|
||||
// save version info
|
||||
ObjectsFileHeader header;
|
||||
ndf << header;
|
||||
|
||||
ndf.setFreeAddress(ndf.getAddress());
|
||||
|
||||
// pre allocate
|
||||
for (alni i = 0; i < SAVE_LOAD_MAX_CALLBACK_SLOTS; i++) {
|
||||
if (sl_callbacks[i]) {
|
||||
DEBUG_ASSERT(sl_callbacks[i]->size);
|
||||
ndf.setFreeAddress(ndf.getFreeAddress() + sl_callbacks[i]->size(sl_callbacks[i]->self, ndf));
|
||||
}
|
||||
}
|
||||
|
||||
tp::alni objects_api::save(ArchiverOut& ndf, Object* in) {
|
||||
// if already saved return file_adress
|
||||
if (NDO_MEMH_FROM_NDO(in)->flags != -1) {
|
||||
return NDO_MEMH_FROM_NDO(in)->flags;
|
||||
}
|
||||
|
||||
// save write adress for parent save function call
|
||||
tp::alni tmp_adress = ndf.getAddress();
|
||||
|
||||
// save requested object to first available adress
|
||||
tp::alni save_adress = ndf.getFreeAddress();
|
||||
|
||||
// save file_adress in memhead
|
||||
NDO_MEMH_FROM_NDO(in)->flags = save_adress;
|
||||
|
||||
// update write adress
|
||||
ndf.setAddress(save_adress);
|
||||
|
||||
// save file object header
|
||||
ObjectFileHead ofh = { 0, getrefc(in) };
|
||||
ndf << ofh;
|
||||
|
||||
save_string(ndf, in->type->name);
|
||||
|
||||
// allocate for object file header
|
||||
ndf.setFreeAddress(ndf.getFreeAddress() + sizeof(ObjectFileHead) + save_string_size(in->type->name));
|
||||
|
||||
// calc max size needed for saving all hierarchy of types
|
||||
tp::alni file_alloc_size = objsize_file_util(in, in->type);
|
||||
|
||||
// offes first available adress
|
||||
ndf.setFreeAddress(ndf.getFreeAddress() + file_alloc_size);
|
||||
|
||||
object_recursive_save(ndf, in, in->type);
|
||||
|
||||
// restore adress for parent save function
|
||||
ndf.setAddress(tmp_adress);
|
||||
|
||||
// return addres of saved object in file space
|
||||
return save_adress;
|
||||
}
|
||||
|
||||
void object_recursive_load(ArchiverIn& ndf, Object* out, const ObjectType* type) {
|
||||
if (type->base) {
|
||||
object_recursive_load(ndf, out, type->base);
|
||||
}
|
||||
|
||||
// automatically offsets for parent type to read
|
||||
if (type->load) {
|
||||
type->load(ndf, out);
|
||||
// pre-save
|
||||
for (alni i = 0; i < SAVE_LOAD_MAX_CALLBACK_SLOTS; i++) {
|
||||
if (sl_callbacks[i] && sl_callbacks[i]->pre_save) {
|
||||
sl_callbacks[i]->pre_save(sl_callbacks[i]->self, ndf);
|
||||
}
|
||||
}
|
||||
|
||||
Object* objects_api::load(ArchiverIn& ndf, tp::alni file_adress) {
|
||||
// check if already saved
|
||||
if (((ObjectFileHead*) (loaded_file + file_adress))->load_head_adress) {
|
||||
return ((ObjectFileHead*) (loaded_file + file_adress))->load_head_adress;
|
||||
save(ndf, in);
|
||||
|
||||
// post-save
|
||||
for (alni i = 0; i < SAVE_LOAD_MAX_CALLBACK_SLOTS; i++) {
|
||||
if (sl_callbacks[i] && sl_callbacks[i]->post_save) {
|
||||
sl_callbacks[i]->post_save(sl_callbacks[i]->self, ndf);
|
||||
}
|
||||
|
||||
// save read address
|
||||
tp::alni parent_file_adress = ndf.getAddress();
|
||||
|
||||
// set read address
|
||||
ndf.setAddress(file_adress);
|
||||
|
||||
ObjectFileHead ofh;
|
||||
ndf >> ofh;
|
||||
|
||||
std::string type_name;
|
||||
load_string(ndf, type_name);
|
||||
|
||||
const ObjectType* object_type = NDO->types.get(type_name);
|
||||
Object* out = ObjectMemAllocate(object_type);
|
||||
|
||||
if (!out) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
setrefc(out, 0);
|
||||
|
||||
// check for null object
|
||||
if (out->type == &NullObject::TypeData) {
|
||||
ObjectMemDeallocate(out);
|
||||
out = NdoNull_globalInstance;
|
||||
}
|
||||
|
||||
// save heap adress in "loaded_file"
|
||||
((ObjectFileHead*) (loaded_file + file_adress))->load_head_adress = out;
|
||||
|
||||
// loads recursively
|
||||
object_recursive_load(ndf, out, object_type);
|
||||
|
||||
// restore read address for parent call to continue
|
||||
ndf.setAddress(parent_file_adress);
|
||||
|
||||
// return heap memory adress
|
||||
return out;
|
||||
}
|
||||
|
||||
bool objects_api::save(Object* in, const std::string& path, bool compressed) {
|
||||
ArchiverOut ndf(path.c_str());
|
||||
// TODO : add compression
|
||||
/*
|
||||
if (compressed) {
|
||||
auto temp = path + ".bz2";
|
||||
compressF2F(path.read(), temp.cstr());
|
||||
|
||||
if (!ndf.isOpened()) {
|
||||
return false;
|
||||
}
|
||||
File::remove(path.read());
|
||||
File::rename(temp.cstr(), path.read());
|
||||
}
|
||||
*/
|
||||
|
||||
clear_object_flags();
|
||||
return true;
|
||||
}
|
||||
|
||||
// save version info
|
||||
ObjectsFileHeader header;
|
||||
ndf << header;
|
||||
Object* objects_api::load(const std::string& path) {
|
||||
/*
|
||||
auto temp_file_name = path + ".unz";
|
||||
bool unz_res = decompressF2F(path.cstr(), temp_file_name.cstr());
|
||||
|
||||
ndf.setFreeAddress(ndf.getAddress());
|
||||
|
||||
// pre allocate
|
||||
for (tp::alni i = 0; i < SAVE_LOAD_MAX_CALLBACK_SLOTS; i++) {
|
||||
if (sl_callbacks[i]) {
|
||||
DEBUG_ASSERT(sl_callbacks[i]->size);
|
||||
ndf.setFreeAddress(ndf.getFreeAddress() + sl_callbacks[i]->size(sl_callbacks[i]->self, ndf));
|
||||
}
|
||||
}
|
||||
|
||||
// pre-save
|
||||
for (tp::alni i = 0; i < SAVE_LOAD_MAX_CALLBACK_SLOTS; i++) {
|
||||
if (sl_callbacks[i] && sl_callbacks[i]->pre_save) {
|
||||
sl_callbacks[i]->pre_save(sl_callbacks[i]->self, ndf);
|
||||
}
|
||||
}
|
||||
|
||||
save(ndf, in);
|
||||
|
||||
// post-save
|
||||
for (tp::alni i = 0; i < SAVE_LOAD_MAX_CALLBACK_SLOTS; i++) {
|
||||
if (sl_callbacks[i] && sl_callbacks[i]->post_save) {
|
||||
sl_callbacks[i]->post_save(sl_callbacks[i]->self, ndf);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO : add compression
|
||||
/*
|
||||
if (compressed) {
|
||||
auto temp = path + ".bz2";
|
||||
tp::compressF2F(path.read(), temp.cstr());
|
||||
|
||||
File::remove(path.read());
|
||||
File::rename(temp.cstr(), path.read());
|
||||
}
|
||||
*/
|
||||
|
||||
return true;
|
||||
if (!unz_res) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Object* objects_api::load(const std::string& path) {
|
||||
/*
|
||||
auto temp_file_name = path + ".unz";
|
||||
bool unz_res = tp::decompressF2F(path.cstr(), temp_file_name.cstr());
|
||||
File ndf(temp_file_name.cstr(), osfile_openflags::LOAD);
|
||||
*/
|
||||
|
||||
if (!unz_res) {
|
||||
return nullptr;
|
||||
}
|
||||
ArchiverIn ndf(path.c_str());
|
||||
|
||||
File ndf(temp_file_name.cstr(), tp::osfile_openflags::LOAD);
|
||||
*/
|
||||
|
||||
ArchiverIn ndf(path.c_str());
|
||||
|
||||
if (!ndf.isOpened()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// check for compatibility
|
||||
ObjectsFileHeader current_header;
|
||||
ObjectsFileHeader loaded_header(false);
|
||||
|
||||
ndf >> loaded_header;
|
||||
|
||||
if (!tp::memEqual(¤t_header, &loaded_header, sizeof(ObjectsFileHeader))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ndf.setAddress(0);
|
||||
|
||||
const auto fileSize = ndf.getSize();
|
||||
loaded_file = (tp::int1*) malloc(fileSize);
|
||||
tp::memSetVal(loaded_file, fileSize, 0);
|
||||
ndf.readBytes(loaded_file, fileSize);
|
||||
|
||||
ndf.setAddress(sizeof(ObjectsFileHeader));
|
||||
|
||||
// preload
|
||||
for (tp::alni i = 0; i < SAVE_LOAD_MAX_CALLBACK_SLOTS; i++) {
|
||||
if (sl_callbacks[i] && sl_callbacks[i]->pre_load) {
|
||||
sl_callbacks[i]->pre_load(sl_callbacks[i]->self, ndf);
|
||||
}
|
||||
}
|
||||
|
||||
Object* out = load(ndf, ndf.getAddress());
|
||||
|
||||
// post
|
||||
for (tp::alni i = 0; i < SAVE_LOAD_MAX_CALLBACK_SLOTS; i++) {
|
||||
if (sl_callbacks[i] && sl_callbacks[i]->post_save) {
|
||||
sl_callbacks[i]->post_load(sl_callbacks[i]->self, ndf);
|
||||
}
|
||||
}
|
||||
|
||||
free(loaded_file);
|
||||
|
||||
/*
|
||||
ndf.close();
|
||||
|
||||
if (unz_res == nullptr) {
|
||||
File::remove(temp_file_name.cstr());
|
||||
}
|
||||
*/
|
||||
|
||||
return out;
|
||||
if (!ndf.isOpened()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void objects_api::add_sl_callbacks(save_load_callbacks* in) {
|
||||
sl_callbacks[sl_callbacks_load_idx] = in;
|
||||
sl_callbacks_load_idx++;
|
||||
// check for compatibility
|
||||
ObjectsFileHeader current_header;
|
||||
ObjectsFileHeader loaded_header(false);
|
||||
|
||||
ndf >> loaded_header;
|
||||
|
||||
if (!memEqual(¤t_header, &loaded_header, sizeof(ObjectsFileHeader))) {
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
ndf.setAddress(0);
|
||||
|
||||
const auto fileSize = ndf.getSize();
|
||||
loaded_file = (int1*) malloc(fileSize);
|
||||
memSetVal(loaded_file, fileSize, 0);
|
||||
ndf.readBytes(loaded_file, fileSize);
|
||||
|
||||
ndf.setAddress(sizeof(ObjectsFileHeader));
|
||||
|
||||
// preload
|
||||
for (alni i = 0; i < SAVE_LOAD_MAX_CALLBACK_SLOTS; i++) {
|
||||
if (sl_callbacks[i] && sl_callbacks[i]->pre_load) {
|
||||
sl_callbacks[i]->pre_load(sl_callbacks[i]->self, ndf);
|
||||
}
|
||||
}
|
||||
|
||||
Object* out = load(ndf, ndf.getAddress());
|
||||
|
||||
// post
|
||||
for (alni i = 0; i < SAVE_LOAD_MAX_CALLBACK_SLOTS; i++) {
|
||||
if (sl_callbacks[i] && sl_callbacks[i]->post_save) {
|
||||
sl_callbacks[i]->post_load(sl_callbacks[i]->self, ndf);
|
||||
}
|
||||
}
|
||||
|
||||
free(loaded_file);
|
||||
|
||||
/*
|
||||
ndf.close();
|
||||
|
||||
if (unz_res == nullptr) {
|
||||
File::remove(temp_file_name.cstr());
|
||||
}
|
||||
*/
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void objects_api::add_sl_callbacks(save_load_callbacks* in) {
|
||||
sl_callbacks[sl_callbacks_load_idx] = in;
|
||||
sl_callbacks_load_idx++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
#include "primitives/StringObject.hpp"
|
||||
#include "primitives/TypeObject.hpp"
|
||||
|
||||
using namespace obj;
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
static void defineTypes() {
|
||||
NDO->define(&DictObject::TypeData);
|
||||
|
|
@ -50,9 +50,9 @@ static void defineGroups() {
|
|||
NDO->type_groups.addType(&InterpreterObject::TypeData, { "scripting" });
|
||||
}
|
||||
|
||||
static bool init(const tp::ModuleManifest*) {
|
||||
static bool init(const ModuleManifest*) {
|
||||
if (!NDO) NDO = new objects_api();
|
||||
obj::BCgen::init();
|
||||
obj::initialize();
|
||||
|
||||
MethodObject::Initialize();
|
||||
|
||||
|
|
@ -62,12 +62,12 @@ static bool init(const tp::ModuleManifest*) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static void deinit(const tp::ModuleManifest*) {
|
||||
static void deinit(const ModuleManifest*) {
|
||||
|
||||
NullObject::uninit();
|
||||
MethodObject::UnInitialize();
|
||||
|
||||
obj::BCgen::deinit();
|
||||
obj::finalize();
|
||||
|
||||
assertNoLeaks();
|
||||
|
||||
|
|
@ -75,8 +75,8 @@ static void deinit(const tp::ModuleManifest*) {
|
|||
NDO = nullptr;
|
||||
}
|
||||
|
||||
static tp::ModuleManifest* sModuleDependencies[] = {
|
||||
static ModuleManifest* sModuleDependencies[] = {
|
||||
nullptr
|
||||
};
|
||||
|
||||
tp::ModuleManifest obj::gModuleObjects = tp::ModuleManifest("Objects", init, deinit, sModuleDependencies);
|
||||
ModuleManifest obj::gModuleObjects = ModuleManifest("Objects", init, deinit, sModuleDependencies);
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
|
||||
#include "core/ScriptSection.hpp"
|
||||
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
ScriptSection* gScriptSection = nullptr;
|
||||
|
||||
struct script_data_head {
|
||||
tp::alni refc = 0;
|
||||
tp::alni store_adress = 0;
|
||||
alni refc = 0;
|
||||
alni store_adress = 0;
|
||||
};
|
||||
|
||||
void set_script_head_store_adress(Script* in, tp::alni address) { ((script_data_head*) in - 1)->store_adress = address; }
|
||||
void set_script_head_store_adress(Script* in, alni address) { ((script_data_head*) in - 1)->store_adress = address; }
|
||||
|
||||
tp::alni get_script_head_store_adress(Script* in) { return ((script_data_head*) in - 1)->store_adress; }
|
||||
alni get_script_head_store_adress(Script* in) { return ((script_data_head*) in - 1)->store_adress; }
|
||||
|
||||
Script* ScriptSection::createScript() {
|
||||
auto sdhead = (script_data_head*) malloc(sizeof(script_data_head) + sizeof(Script));
|
||||
|
|
@ -29,7 +30,7 @@ Script* ScriptSection::createScript() {
|
|||
|
||||
new (out) Script();
|
||||
out->mReadable = obj::StringObject::create("");
|
||||
obj::NDO->refinc(out->mReadable);
|
||||
obj::NDO->increaseReferenceCount(out->mReadable);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
@ -60,29 +61,29 @@ void ScriptSection::changeScript(Script** current_script, Script** new_script) {
|
|||
*current_script = *new_script;
|
||||
}
|
||||
|
||||
tp::alni ScriptSection::get_script_file_adress(Script* in) { return get_script_head_store_adress(in); }
|
||||
alni ScriptSection::get_script_file_adress(Script* in) { return get_script_head_store_adress(in); }
|
||||
|
||||
tp::alni ScriptSection::save_script_table_to_file_size(ScriptSection* self, ArchiverOut& file) {
|
||||
tp::alni size = 0;
|
||||
alni ScriptSection::save_script_table_to_file_size(ScriptSection* self, ArchiverOut& file) {
|
||||
alni size = 0;
|
||||
size += 5; // header
|
||||
size += sizeof(tp::alni); // scripts length
|
||||
size += sizeof(alni); // scripts length
|
||||
|
||||
for (auto iter : self->mScripts) {
|
||||
|
||||
set_script_head_store_adress(iter.data(), file.getAddress() + size);
|
||||
|
||||
size += sizeof(tp::alni); // scripts string obj ref
|
||||
size += sizeof(tp::alni); // constants length
|
||||
size += sizeof(alni); // scripts string obj ref
|
||||
size += sizeof(alni); // constants length
|
||||
|
||||
for (auto const_obj : iter->mBytecode.mConstants) {
|
||||
size += sizeof(tp::alni); // constant object addres
|
||||
size += sizeof(alni); // constant object addres
|
||||
}
|
||||
|
||||
// instructions
|
||||
size += tp::SaveSizeCounter::calc(iter->mBytecode.mInstructions);
|
||||
size += SaveSizeCounter::calc(iter->mBytecode.mInstructions);
|
||||
}
|
||||
|
||||
size += sizeof(tp::alni); // objects mem offset
|
||||
size += sizeof(alni); // objects mem offset
|
||||
size += 5; // header
|
||||
return size;
|
||||
}
|
||||
|
|
@ -92,7 +93,7 @@ void ScriptSection::save_script_table_to_file(ScriptSection* self, ArchiverOut&
|
|||
file.writeBytes("/scr/", 5);
|
||||
|
||||
// scripts length
|
||||
tp::alni scripts_count = self->mScripts.length();
|
||||
alni scripts_count = self->mScripts.length();
|
||||
file << scripts_count;
|
||||
|
||||
for (auto iter : self->mScripts) {
|
||||
|
|
@ -102,7 +103,7 @@ void ScriptSection::save_script_table_to_file(ScriptSection* self, ArchiverOut&
|
|||
file << obj_addres;
|
||||
|
||||
// constants length
|
||||
tp::alni consts_count = iter->mBytecode.mConstants.size();
|
||||
alni consts_count = iter->mBytecode.mConstants.size();
|
||||
file << consts_count;
|
||||
|
||||
for (auto const_obj : iter->mBytecode.mConstants) {
|
||||
|
|
@ -118,40 +119,40 @@ void ScriptSection::save_script_table_to_file(ScriptSection* self, ArchiverOut&
|
|||
// header
|
||||
file.writeBytes("/scr/", 5);
|
||||
|
||||
tp::alni objects_mem_offset = file.getFreeAddress();
|
||||
alni objects_mem_offset = file.getFreeAddress();
|
||||
file << objects_mem_offset;
|
||||
}
|
||||
|
||||
void load_constants(ScriptSection* self, ArchiverIn& file, tp::alni start_addr) {
|
||||
void load_constants(ScriptSection* self, ArchiverIn& file, alni start_addr) {
|
||||
auto addres = file.getAddress();
|
||||
|
||||
file.setAddress(start_addr);
|
||||
file.setAddress(start_addr + 5); // header
|
||||
|
||||
tp::alni scripts_count;
|
||||
alni scripts_count;
|
||||
file >> scripts_count;
|
||||
|
||||
for (tp::alni i = 0; i < scripts_count; i++) {
|
||||
for (alni i = 0; i < scripts_count; i++) {
|
||||
|
||||
auto script = self->get_scritp_from_file_adress(file.getAddress());
|
||||
|
||||
// script text
|
||||
tp::alni str_addr;
|
||||
alni str_addr;
|
||||
file >> str_addr;
|
||||
|
||||
NDO->destroy(script->mReadable); // we already have string object in the script when creating script
|
||||
script->mReadable = NDO_CAST(obj::StringObject, obj::NDO->load(file, str_addr));
|
||||
|
||||
file.setAddress(file.getAddress() + sizeof(tp::alni)); // constants length
|
||||
file.setAddress(file.getAddress() + sizeof(alni)); // constants length
|
||||
|
||||
for (auto const_obj : script->mBytecode.mConstants) {
|
||||
tp::alni consts_addr;
|
||||
alni consts_addr;
|
||||
file >> consts_addr;
|
||||
const_obj.data() = obj::NDO->load(file, consts_addr);
|
||||
}
|
||||
|
||||
// instructions
|
||||
file.setAddress(file.getAddress() + tp::SaveSizeCounter::calc(script->mBytecode.mInstructions));
|
||||
file.setAddress(file.getAddress() + SaveSizeCounter::calc(script->mBytecode.mInstructions));
|
||||
}
|
||||
|
||||
file.setAddress(addres);
|
||||
|
|
@ -168,26 +169,26 @@ void ScriptSection::load_script_table_from_file(ScriptSection* self, ArchiverIn&
|
|||
file.setAddress(file.getAddress() + 5);
|
||||
|
||||
// scripts length
|
||||
tp::alni scripts_count;
|
||||
alni scripts_count;
|
||||
file >> scripts_count;
|
||||
|
||||
for (tp::alni i = 0; i < scripts_count; i++) {
|
||||
for (alni i = 0; i < scripts_count; i++) {
|
||||
|
||||
auto new_script = self->createScript();
|
||||
set_script_head_store_adress(new_script, file.getAddress());
|
||||
|
||||
// scripts text
|
||||
file.setAddress(file.getAddress() + sizeof(tp::alni));
|
||||
file.setAddress(file.getAddress() + sizeof(alni));
|
||||
|
||||
// constants length
|
||||
tp::alni consts_count;
|
||||
alni consts_count;
|
||||
file >> consts_count;
|
||||
|
||||
new_script->mBytecode.mConstants.reserve(consts_count);
|
||||
|
||||
for (tp::alni j = 0; j < consts_count; j++) {
|
||||
for (alni j = 0; j < consts_count; j++) {
|
||||
// constant object addres
|
||||
tp::alni consts_addr;
|
||||
alni consts_addr;
|
||||
file >> consts_addr;
|
||||
|
||||
// skiping
|
||||
|
|
@ -203,13 +204,13 @@ void ScriptSection::load_script_table_from_file(ScriptSection* self, ArchiverIn&
|
|||
// header
|
||||
file.setAddress(file.getAddress() + 5);
|
||||
|
||||
tp::alni objects_mem_offset;
|
||||
alni objects_mem_offset;
|
||||
file >> objects_mem_offset;
|
||||
|
||||
file.setAddress(objects_mem_offset);
|
||||
}
|
||||
|
||||
Script* ScriptSection::get_scritp_from_file_adress(tp::alni file_adress) {
|
||||
Script* ScriptSection::get_scritp_from_file_adress(alni file_adress) {
|
||||
for (auto iter : mScripts) {
|
||||
if (get_script_head_store_adress(iter.data()) == file_adress) {
|
||||
return iter.data();
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "core/Object.hpp"
|
||||
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
obj::TypeGroups::TypeGroups() :
|
||||
|
|
@ -31,10 +32,10 @@ void obj::TypeGroups::setType(ObjectType* type) {
|
|||
this->type = type;
|
||||
}
|
||||
|
||||
void obj::TypeGroups::addType(ObjectType* type, tp::InitialierList<const char*> path, tp::alni cur_dir_idx) {
|
||||
void obj::TypeGroups::addType(ObjectType* type, InitialierList<const char*> path, alni cur_dir_idx) {
|
||||
DEBUG_ASSERT(is_group);
|
||||
|
||||
tp::alni dir_len = (tp::alni) path.size();
|
||||
alni dir_len = (alni) path.size();
|
||||
|
||||
if (dir_len == cur_dir_idx) {
|
||||
TypeGroups* type_ref = new TypeGroups(false);
|
||||
|
|
@ -44,7 +45,7 @@ void obj::TypeGroups::addType(ObjectType* type, tp::InitialierList<const char*>
|
|||
}
|
||||
|
||||
TypeGroups* group = nullptr;
|
||||
tp::alni index = 0;
|
||||
alni index = 0;
|
||||
|
||||
for (auto dir : path) {
|
||||
if (index != cur_dir_idx) {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "interpreter/Interpreter.hpp"
|
||||
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
TypeMethod obj::gDefaultTypeMethods[] = {
|
||||
|
|
@ -40,17 +41,17 @@ TypeMethod obj::gDefaultTypeMethods[] = {
|
|||
},
|
||||
};
|
||||
|
||||
tp::int2 TypeMethods::presents(const std::string& id) const {
|
||||
for (tp::int2 idx = 0; idx < mNMethods; idx++) {
|
||||
int2 TypeMethods::presents(const std::string& id) const {
|
||||
for (int2 idx = 0; idx < mNMethods; idx++) {
|
||||
if (id == methods[idx]->nameid) {
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
tp::int2 idx = 0;
|
||||
int2 idx = 0;
|
||||
for (auto& tm : gDefaultTypeMethods) {
|
||||
if (id == tm.nameid) {
|
||||
return { tp::int2(idx + MAX_TYPE_METHODS) };
|
||||
return { int2(idx + MAX_TYPE_METHODS) };
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
|
|
@ -60,8 +61,8 @@ tp::int2 TypeMethods::presents(const std::string& id) const {
|
|||
|
||||
TypeMethods::LookupKey TypeMethods::presents(const ObjectType* type, const std::string& id) {
|
||||
|
||||
tp::int2 depth = 0;
|
||||
tp::int2 idx = 0;
|
||||
int2 depth = 0;
|
||||
int2 idx = 0;
|
||||
|
||||
for (auto iter_type = type; iter_type; iter_type = iter_type->base) {
|
||||
idx = iter_type->type_methods.presents(id);
|
||||
|
|
@ -74,7 +75,7 @@ TypeMethods::LookupKey TypeMethods::presents(const ObjectType* type, const std::
|
|||
return { idx, depth };
|
||||
}
|
||||
|
||||
const TypeMethod* TypeMethods::getMethod(tp::int2 key) const {
|
||||
const TypeMethod* TypeMethods::getMethod(int2 key) const {
|
||||
if (key < MAX_TYPE_METHODS) {
|
||||
return methods[key];
|
||||
}
|
||||
|
|
@ -94,14 +95,14 @@ void TypeMethods::init() {
|
|||
mNMethods++;
|
||||
}
|
||||
|
||||
for (tp::int1 i = 0; i < mNMethods; i++) {
|
||||
for (int1 i = 0; i < mNMethods; i++) {
|
||||
methods[i]->init();
|
||||
}
|
||||
|
||||
// initialize and use finate state automata to lookup methods
|
||||
}
|
||||
|
||||
tp::halni TypeMethods::nMethods() const { return mNMethods; }
|
||||
halni TypeMethods::nMethods() const { return mNMethods; }
|
||||
|
||||
void TypeMethod::operator()(Interpreter* interp) const {
|
||||
for (auto i = 1; i <= mNargs; i++) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "interpreter/ByteCode.hpp"
|
||||
#include "primitives/MethodObject.hpp"
|
||||
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
void CallStack::enter(const CallStack::CallFrame& frame) {
|
||||
|
|
@ -14,7 +15,7 @@ void CallStack::enter(const CallStack::CallFrame& frame) {
|
|||
|
||||
frame.mMethod->mScript->mBytecode.mArgumentsLoaded = 0;
|
||||
frame.mMethod->mScript->mBytecode.mInstructionIdx = 0;
|
||||
obj::NDO->refinc(frame.mMethod);
|
||||
obj::NDO->increaseReferenceCount(frame.mMethod);
|
||||
mStack.append(frame);
|
||||
}
|
||||
|
||||
|
|
@ -31,4 +32,4 @@ void CallStack::leave() {
|
|||
|
||||
ByteCode* CallStack::getBytecode() { return &mStack.last().mMethod->mScript->mBytecode; }
|
||||
|
||||
tp::halni CallStack::len() const { return mStack.size(); }
|
||||
halni CallStack::len() const { return mStack.size(); }
|
||||
|
|
|
|||
|
|
@ -5,20 +5,21 @@
|
|||
|
||||
#include "Timing.hpp"
|
||||
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
inline tp::uint1 read_byte(ByteCode* bytecode) {
|
||||
auto out = (tp::uint1) bytecode->mInstructions[bytecode->mInstructionIdx];
|
||||
inline uint1 read_byte(ByteCode* bytecode) {
|
||||
auto out = (uint1) bytecode->mInstructions[bytecode->mInstructionIdx];
|
||||
bytecode->mInstructionIdx++;
|
||||
return out;
|
||||
}
|
||||
|
||||
// exeption for opcodes
|
||||
// reads 2 bytes from instructions in order to load constant onto operands stack
|
||||
tp::uint2 loadConstDataIdx(ByteCode* bytecode) {
|
||||
tp::uint2 out = 0;
|
||||
out |= ((tp::uint2) read_byte(bytecode));
|
||||
out |= ((tp::uint2) read_byte(bytecode) << 8);
|
||||
uint2 loadConstDataIdx(ByteCode* bytecode) {
|
||||
uint2 out = 0;
|
||||
out |= ((uint2) read_byte(bytecode));
|
||||
out |= ((uint2) read_byte(bytecode) << 8);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
@ -26,9 +27,9 @@ tp::uint2 loadConstDataIdx(ByteCode* bytecode) {
|
|||
// reads 2 bytes from instructions in order to load constant onto operands stack
|
||||
void skip_param(ByteCode* bytecode) { bytecode->mInstructionIdx += 2; }
|
||||
|
||||
tp::uint2 param(ByteCode* bytecode) { return loadConstDataIdx(bytecode); }
|
||||
uint2 param(ByteCode* bytecode) { return loadConstDataIdx(bytecode); }
|
||||
|
||||
void Interpreter::exec(obj::MethodObject* method, obj::ClassObject* self, obj::DictObject* globals, tp::InitialierList<GlobalDef> globals2) {
|
||||
void Interpreter::exec(obj::MethodObject* method, obj::ClassObject* self, obj::DictObject* globals, InitialierList<GlobalDef> globals2) {
|
||||
if (!method->mScript->mBytecode.mInstructions.size()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -52,7 +53,7 @@ void Interpreter::exec(obj::MethodObject* method, obj::ClassObject* self, obj::D
|
|||
bool Interpreter::finished() { return !mCallStack.len(); }
|
||||
|
||||
void Interpreter::stepBytecode() {
|
||||
tp::halni call_depth = mCallStack.len();
|
||||
halni call_depth = mCallStack.len();
|
||||
do {
|
||||
stepBytecodeIn();
|
||||
if (finished()) {
|
||||
|
|
@ -66,7 +67,7 @@ void Interpreter::stepBytecodeOut() {
|
|||
return;
|
||||
}
|
||||
|
||||
tp::halni call_depth = mCallStack.len();
|
||||
halni call_depth = mCallStack.len();
|
||||
if (!call_depth) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -87,7 +88,7 @@ void Interpreter::stepBytecodeIn() {
|
|||
|
||||
auto bytecode = mCallStack.getBytecode();
|
||||
|
||||
if (bytecode->mInstructionIdx >= (tp::ualni) bytecode->mInstructions.size()) {
|
||||
if (bytecode->mInstructionIdx >= (ualni) bytecode->mInstructions.size()) {
|
||||
// just return
|
||||
if (mScopeStack.mIdx) {
|
||||
mScopeStack.leaveScope();
|
||||
|
|
@ -114,14 +115,14 @@ void Interpreter::stepBytecodeIn() {
|
|||
case OpCode::HALT:
|
||||
{
|
||||
while (true) {
|
||||
tp::sleep(3);
|
||||
sleep(3);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::TERMINATE:
|
||||
{
|
||||
// tp::terminate(0);
|
||||
// terminate(0);
|
||||
}
|
||||
|
||||
case OpCode::IGNORE:
|
||||
|
|
@ -242,7 +243,7 @@ void Interpreter::stepBytecodeIn() {
|
|||
auto id = mOperandsStack.getOperand<StringObject>();
|
||||
auto obj = mOperandsStack.getOperand();
|
||||
mScopeStack.addLocal(obj, id->val);
|
||||
NDO->refinc(obj);
|
||||
NDO->increaseReferenceCount(obj);
|
||||
// mScopeStack.popTemp();
|
||||
break;
|
||||
}
|
||||
|
|
@ -270,7 +271,7 @@ void Interpreter::stepBytecodeIn() {
|
|||
// class is a function - execute it as a constructor
|
||||
|
||||
// PUSH_ARGS protocol
|
||||
tp::uint2 len = 0;
|
||||
uint2 len = 0;
|
||||
mOperandsStack.push((Object*) len);
|
||||
mOperandsStack.push(nullptr);
|
||||
|
||||
|
|
@ -318,7 +319,7 @@ void Interpreter::stepBytecodeIn() {
|
|||
// +4) object2
|
||||
// ...
|
||||
|
||||
tp::uint2 len = read_byte(bytecode);
|
||||
uint2 len = read_byte(bytecode);
|
||||
mOperandsStack.push((Object*) len);
|
||||
mOperandsStack.push(nullptr);
|
||||
break;
|
||||
|
|
@ -326,11 +327,11 @@ void Interpreter::stepBytecodeIn() {
|
|||
|
||||
case OpCode::SAVE_ARGS:
|
||||
{
|
||||
tp::uint2 args_len = read_byte(bytecode);
|
||||
uint2 args_len = read_byte(bytecode);
|
||||
auto argument = mOperandsStack.getOperand();
|
||||
|
||||
while (argument) {
|
||||
NDO->refinc(argument);
|
||||
NDO->increaseReferenceCount(argument);
|
||||
|
||||
auto argument_id = bytecode->mConstants[loadConstDataIdx(bytecode)];
|
||||
NDO_CASTV(StringObject, argument_id, id);
|
||||
|
|
@ -340,7 +341,7 @@ void Interpreter::stepBytecodeIn() {
|
|||
argument = mOperandsStack.getOperand();
|
||||
}
|
||||
|
||||
tp::uint2 saved_len = tp::uint2(tp::ualni(mOperandsStack.getOperand()));
|
||||
uint2 saved_len = uint2(ualni(mOperandsStack.getOperand()));
|
||||
ASSERT(args_len == saved_len && "invalid number of arguments passefd");
|
||||
|
||||
break;
|
||||
|
|
@ -388,7 +389,7 @@ void Interpreter::stepBytecodeIn() {
|
|||
ASSERT(left->type == right->type && "addition of different types is not implemented");
|
||||
ASSERT(left->type->ariphmetics && left->type->ariphmetics->add && "cannot add object of this type");
|
||||
|
||||
auto res = NDO->instatiate(left);
|
||||
auto res = NDO->instantiate(left);
|
||||
res->type->ariphmetics->add(res, right);
|
||||
|
||||
mScopeStack.addTemp(res);
|
||||
|
|
@ -403,7 +404,7 @@ void Interpreter::stepBytecodeIn() {
|
|||
ASSERT(left->type == right->type && "addition of different types is not implemented");
|
||||
ASSERT(left->type->ariphmetics && left->type->ariphmetics->add && "cannot add object of this type");
|
||||
|
||||
auto res = NDO->instatiate(left);
|
||||
auto res = NDO->instantiate(left);
|
||||
res->type->ariphmetics->sub(res, right);
|
||||
|
||||
mScopeStack.addTemp(res);
|
||||
|
|
@ -418,7 +419,7 @@ void Interpreter::stepBytecodeIn() {
|
|||
ASSERT(left->type == right->type && "addition of different types is not implemented");
|
||||
ASSERT(left->type->ariphmetics && left->type->ariphmetics->add && "cannot add object of this type");
|
||||
|
||||
auto res = NDO->instatiate(left);
|
||||
auto res = NDO->instantiate(left);
|
||||
res->type->ariphmetics->mul(res, right);
|
||||
|
||||
mScopeStack.addTemp(res);
|
||||
|
|
@ -433,7 +434,7 @@ void Interpreter::stepBytecodeIn() {
|
|||
ASSERT(left->type == right->type && "addition of different types is not implemented");
|
||||
ASSERT(left->type->ariphmetics && left->type->ariphmetics->add && "cannot add object of this type");
|
||||
|
||||
auto res = NDO->instatiate(left);
|
||||
auto res = NDO->instantiate(left);
|
||||
res->type->ariphmetics->div(res, right);
|
||||
|
||||
mScopeStack.addTemp(res);
|
||||
|
|
@ -593,7 +594,7 @@ void Interpreter::stepBytecodeIn() {
|
|||
}
|
||||
}
|
||||
|
||||
void Interpreter::execAll(obj::MethodObject* method, obj::ClassObject* self, obj::DictObject* globals, tp::InitialierList<GlobalDef> globals2) {
|
||||
void Interpreter::execAll(obj::MethodObject* method, obj::ClassObject* self, obj::DictObject* globals, InitialierList<GlobalDef> globals2) {
|
||||
if (!method->mScript->mBytecode.mInstructions.size()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
#include "interpreter/OperandsStack.hpp"
|
||||
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
OperandStack::OperandStack() {
|
||||
|
|
|
|||
|
|
@ -3,18 +3,17 @@
|
|||
|
||||
#include "interpreter/OperatoinCodes.hpp"
|
||||
|
||||
namespace obj {
|
||||
OpcodeInfos gOpcodeInfos;
|
||||
};
|
||||
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
OpcodeInfos tp::obj::gOpcodeInfos;
|
||||
|
||||
#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) {
|
||||
OpcodeInfos::OperandsInfo::OperandsInfo(InitialierList<Operand> list) {
|
||||
DEBUG_ASSERT(MAX_OPERANDS >= list.size());
|
||||
for (auto item : list) {
|
||||
buff[len] = item;
|
||||
|
|
@ -23,7 +22,7 @@ OpcodeInfos::OperandsInfo::OperandsInfo(tp::InitialierList<Operand> list) {
|
|||
}
|
||||
|
||||
OpcodeInfos::ParamsInfo::ParamsInfo() {}
|
||||
OpcodeInfos::ParamsInfo::ParamsInfo(tp::InitialierList<Param> list) {
|
||||
OpcodeInfos::ParamsInfo::ParamsInfo(InitialierList<Param> list) {
|
||||
DEBUG_ASSERT(MAX_PARAMS >= list.size());
|
||||
for (auto item : list) {
|
||||
buff[len] = item;
|
||||
|
|
@ -31,8 +30,8 @@ OpcodeInfos::ParamsInfo::ParamsInfo(tp::InitialierList<Param> list) {
|
|||
}
|
||||
}
|
||||
|
||||
tp::uint1 OpcodeInfos::OpInfo::opsize() {
|
||||
tp::uint1 out = 1;
|
||||
uint1 OpcodeInfos::OpInfo::opsize() {
|
||||
uint1 out = 1;
|
||||
for (auto i = 0; i < params.len; i++) {
|
||||
out += params.buff[i].bytes;
|
||||
}
|
||||
|
|
@ -364,8 +363,8 @@ OpcodeInfos::OpcodeInfos() {
|
|||
}
|
||||
|
||||
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];
|
||||
DEBUG_ASSERT((alni) code >= 0 && (alni) code < (alni) OpCode::END_OPCODES);
|
||||
return buff[(alni) code];
|
||||
}
|
||||
|
||||
void OpcodeInfos::add(OpCode code, const OpInfo& info) { buff[(tp::alni) code] = info; }
|
||||
void OpcodeInfos::add(OpCode code, const OpInfo& info) { buff[(alni) code] = info; }
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
#include "interpreter/ScopeStack.hpp"
|
||||
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
Scope::~Scope() {
|
||||
|
|
@ -46,7 +47,7 @@ void ScopeStack::leaveScope() {
|
|||
}
|
||||
|
||||
void ScopeStack::addTemp(obj::Object* tmp) {
|
||||
obj::NDO->refinc(tmp);
|
||||
obj::NDO->increaseReferenceCount(tmp);
|
||||
mBuff[mIdx - 1].mTemps.pushBack(tmp);
|
||||
}
|
||||
|
||||
|
|
@ -57,7 +58,7 @@ void ScopeStack::popTemp() {
|
|||
|
||||
void ScopeStack::addTempReturn(obj::Object* ret) {
|
||||
if (mIdx >= 2) {
|
||||
obj::NDO->refinc(ret);
|
||||
obj::NDO->increaseReferenceCount(ret);
|
||||
mBuff[mIdx - 2].mTemps.pushBack(ret);
|
||||
}
|
||||
}
|
||||
|
|
@ -69,7 +70,7 @@ void ScopeStack::addLocal(obj::Object* local, const std::string& id) {
|
|||
if (idx) {
|
||||
obj::NDO->destroy(locals.getSlotVal(idx));
|
||||
}
|
||||
obj::NDO->refinc(local);
|
||||
obj::NDO->increaseReferenceCount(local);
|
||||
locals.put(id, local);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
|
||||
#include "Private.hpp"
|
||||
|
||||
using namespace obj::BCgen;
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
typedef lalr::ParserNode<SymbolType> Node;
|
||||
|
||||
|
|
@ -189,7 +190,7 @@ static UserData tmp(const UserData* start, const Node*, size_t) {
|
|||
|
||||
#define BIND(name) parser.set_action_handler(#name, &(name))
|
||||
|
||||
void bind(LalrParser& parser) {
|
||||
void obj::bind(LalrParser& parser) {
|
||||
BIND(scope);
|
||||
|
||||
BIND(stm_list_append);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "Private.hpp"
|
||||
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
lalr::ErrorPolicy::~ErrorPolicy() = default;
|
||||
|
|
@ -37,10 +38,10 @@ Parser::Result Parser::parse(const std::string& stream) {
|
|||
|
||||
parser.parse(streamStd.begin(), streamStd.end());
|
||||
|
||||
BCgen::StatementScope* out = nullptr;
|
||||
StatementScope* out = nullptr;
|
||||
|
||||
if (parser.accepted() && parser.full()) {
|
||||
out = (BCgen::StatementScope*) parser.user_data().statement;
|
||||
out = (StatementScope*) parser.user_data().statement;
|
||||
}
|
||||
|
||||
return { out, !(parser.accepted() && parser.full()) };
|
||||
|
|
|
|||
|
|
@ -9,42 +9,44 @@
|
|||
|
||||
#include "Tree.hpp"
|
||||
|
||||
struct UserNode {
|
||||
obj::BCgen::Expression* expression = nullptr;
|
||||
obj::BCgen::Statement* statement = nullptr;
|
||||
tp::Buffer<std::string>* arguments = nullptr;
|
||||
|
||||
UserNode(obj::BCgen::Statement* stm) :
|
||||
statement(stm) {}
|
||||
|
||||
UserNode(obj::BCgen::Expression* expr) :
|
||||
expression(expr) {}
|
||||
|
||||
UserNode(tp::Buffer<std::string>* argList) :
|
||||
arguments(argList) {}
|
||||
|
||||
UserNode() = default;
|
||||
|
||||
obj::BCgen::Statement* releaseStm() {
|
||||
auto out = statement;
|
||||
statement = nullptr;
|
||||
return out;
|
||||
}
|
||||
|
||||
void destroy() {
|
||||
delete statement;
|
||||
delete arguments;
|
||||
delete expression;
|
||||
}
|
||||
};
|
||||
|
||||
typedef UserNode UserData;
|
||||
typedef char SymbolType;
|
||||
|
||||
typedef std::basic_string<SymbolType>::iterator IteratorType;
|
||||
|
||||
extern const lalr::ParserStateMachine* oscript_parser_state_machine;
|
||||
|
||||
typedef lalr::Parser<IteratorType, UserData> LalrParser;
|
||||
namespace tp::obj {
|
||||
struct UserNode {
|
||||
obj::Expression* expression = nullptr;
|
||||
obj::Statement* statement = nullptr;
|
||||
tp::Buffer<std::string>* arguments = nullptr;
|
||||
|
||||
void bind(LalrParser& parser);
|
||||
UserNode(obj::Statement* stm) :
|
||||
statement(stm) {}
|
||||
|
||||
UserNode(obj::Expression* expr) :
|
||||
expression(expr) {}
|
||||
|
||||
UserNode(tp::Buffer<std::string>* argList) :
|
||||
arguments(argList) {}
|
||||
|
||||
UserNode() = default;
|
||||
|
||||
obj::Statement* releaseStm() {
|
||||
auto out = statement;
|
||||
statement = nullptr;
|
||||
return out;
|
||||
}
|
||||
|
||||
void destroy() {
|
||||
delete statement;
|
||||
delete arguments;
|
||||
delete expression;
|
||||
}
|
||||
};
|
||||
|
||||
typedef UserNode UserData;
|
||||
typedef char SymbolType;
|
||||
|
||||
typedef std::basic_string<SymbolType>::iterator IteratorType;
|
||||
|
||||
typedef lalr::Parser<IteratorType, UserData> LalrParser;
|
||||
|
||||
void bind(LalrParser& parser);
|
||||
}
|
||||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
#include "primitives/BoolObject.hpp"
|
||||
|
||||
using namespace obj;
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
void BoolObject::constructor(BoolObject* self) { self->val = false; }
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
#include "primitives/DictObject.hpp"
|
||||
#include "primitives/NullObject.hpp"
|
||||
|
||||
using namespace obj;
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
void ClassObject::constructor(ClassObject* self) {
|
||||
self->members = NDO_CAST(DictObject, NDO->create("dict"));
|
||||
|
|
@ -38,7 +38,7 @@ void ClassObject::load(ArchiverIn& file_self, ClassObject* self) {
|
|||
alni ndo_object_adress;
|
||||
file_self >> ndo_object_adress;
|
||||
self->members = NDO_CAST(DictObject, NDO->load(file_self, ndo_object_adress));
|
||||
NDO->refinc(self->members);
|
||||
NDO->increaseReferenceCount(self->members);
|
||||
}
|
||||
|
||||
tp::Buffer<Object*> childs_retrival(ClassObject* self) {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
|
||||
#include "primitives/ColorObject.hpp"
|
||||
|
||||
using namespace obj;
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
void ColorObject::constructor(Object* self) { NDO_CAST(ColorObject, self)->mCol = tp::RGBA(1.f); }
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
#include "primitives/DictObject.hpp"
|
||||
#include "primitives/StringObject.hpp"
|
||||
|
||||
using namespace obj;
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
void DictObject::constructor(Object* self) {
|
||||
NDO_CASTV(DictObject, self, dict);
|
||||
|
|
@ -19,7 +19,7 @@ void DictObject::copy(Object* in, const Object* target) {
|
|||
constructor(self);
|
||||
|
||||
for (auto item : src->items) {
|
||||
auto instance = NDO->instatiate(item->val);
|
||||
auto instance = NDO->instantiate(item->val);
|
||||
self->items.put(item->key, instance);
|
||||
}
|
||||
}
|
||||
|
|
@ -120,7 +120,7 @@ alni DictObject::allocated_size_recursive(DictObject* self) {
|
|||
|
||||
void DictObject::put(const std::string& str, Object* obj) {
|
||||
DEBUG_ASSERT(obj);
|
||||
NDO->refinc(obj);
|
||||
NDO->increaseReferenceCount(obj);
|
||||
items.put(str, obj);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
#include <malloc.h>
|
||||
#include <cstring>
|
||||
|
||||
using namespace obj;
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
void EnumObject::constructor(EnumObject* self) {
|
||||
self->active = 0;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "primitives/FloatObject.hpp"
|
||||
|
||||
using namespace obj;
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
void FloatObject::constructor(FloatObject* self) { self->val = 0; }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
|
||||
#include "primitives/IntObject.hpp"
|
||||
|
||||
using namespace obj;
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
void IntObject::constructor(Object* self) { NDO_CAST(IntObject, self)->val = 0; }
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
#include "primitives/LinkObject.hpp"
|
||||
#include "primitives/MethodObject.hpp"
|
||||
|
||||
using namespace obj;
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
void InterpreterObject::constructor(InterpreterObject* self) {
|
||||
new (&self->mInterpreter) Interpreter();
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
|
||||
#include "primitives/LinkObject.hpp"
|
||||
|
||||
using namespace obj;
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
void LinkObject::constructor(Object* self) { NDO_CAST(LinkObject, self)->link = 0; }
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ void LinkObject::load(ArchiverIn& file_self, LinkObject* self) {
|
|||
self->link = nullptr;
|
||||
} else {
|
||||
self->link = NDO->load(file_self, saved_object_adress);
|
||||
NDO->refinc(self->link);
|
||||
NDO->increaseReferenceCount(self->link);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ Object* LinkObject::getLink() { return link; }
|
|||
|
||||
void LinkObject::setLink(Object* obj) {
|
||||
if (link) NDO->destroy(link);
|
||||
if (obj) NDO->refinc(obj);
|
||||
if (obj) NDO->increaseReferenceCount(obj);
|
||||
link = obj;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
#include "primitives/IntObject.hpp"
|
||||
#include "primitives/ListObject.hpp"
|
||||
|
||||
using namespace obj;
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
void ListObject::constructor(Object* in) {
|
||||
NDO_CASTV(ListObject, in, self);
|
||||
|
|
@ -17,7 +17,7 @@ void ListObject::copy(Object* in, const Object* target) {
|
|||
destructor(in);
|
||||
|
||||
for (auto item : src->items) {
|
||||
self->pushBack(NDO->instatiate(item.data()));
|
||||
self->pushBack(NDO->instantiate(item.data()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -84,12 +84,12 @@ alni ListObject::allocated_size_recursive(ListObject* self) {
|
|||
}
|
||||
|
||||
void ListObject::pushBack(Object* obj) {
|
||||
obj::NDO->refinc(obj);
|
||||
obj::NDO->increaseReferenceCount(obj);
|
||||
items.pushBack(obj);
|
||||
}
|
||||
|
||||
void ListObject::pushFront(Object* obj) {
|
||||
obj::NDO->refinc(obj);
|
||||
obj::NDO->increaseReferenceCount(obj);
|
||||
items.pushFront(obj);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "core/ScriptSection.hpp"
|
||||
#include "primitives/MethodObject.hpp"
|
||||
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
struct ObjectType MethodObject::TypeData = {
|
||||
|
|
@ -52,7 +53,7 @@ void MethodObject::Initialize() {
|
|||
|
||||
void MethodObject::UnInitialize() { obj::ScriptSection::uninitialize(); }
|
||||
|
||||
void MethodObject::compile() { BCgen::Compile(this); }
|
||||
void MethodObject::compile() { Compile(this); }
|
||||
|
||||
MethodObject* MethodObject::create(const std::string& script) {
|
||||
auto out = (MethodObject*) NDO->create(MethodObject::TypeData.name);
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
#include "primitives/NullObject.hpp"
|
||||
|
||||
using namespace obj;
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
obj::NullObject* obj::NdoNull_globalInstance = nullptr;
|
||||
bool uninit_flag = false;
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
#include "primitives/StringObject.hpp"
|
||||
|
||||
using namespace obj;
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
void StringObject::constructor(Object* self) { new (&NDO_CAST(StringObject, self)->val) std::string(); }
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
#include "primitives/TypeObject.hpp"
|
||||
#include "primitives/NullObject.hpp"
|
||||
|
||||
using namespace obj;
|
||||
using namespace tp;
|
||||
using namespace obj;
|
||||
|
||||
TypeObject* TypeObject::create(const ObjectType* type) {
|
||||
NDO_CASTV(TypeObject, NDO->create("typeobject"), out);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue