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,92 +1,91 @@
#include "NewPlacement.hpp"
#include "Tokenizer.hpp"
#include "compiler/function.h"
#include "primitives/boolobject.h"
#include "primitives/classobject.h"
#include "primitives/colorobject.h"
#include "primitives/dictobject.h"
#include "primitives/enumobject.h"
#include "primitives/floatobject.h"
#include "primitives/interpreterobject.h"
#include "primitives/intobject.h"
#include "primitives/linkobject.h"
#include "primitives/listobject.h"
#include "primitives/methodobject.h"
#include "primitives/nullobject.h"
#include "primitives/stringobject.h"
#include "primitives/typeobject.h"
using namespace obj;
using namespace tp;
static void defineTypes() {
NDO->define(&DictObject::TypeData);
NDO->define(&IntObject::TypeData);
NDO->define(&LinkObject::TypeData);
NDO->define(&ListObject::TypeData);
NDO->define(&NullObject::TypeData);
NDO->define(&StringObject::TypeData);
NDO->define(&BoolObject::TypeData);
NDO->define(&FloatObject::TypeData);
NDO->define(&EnumObject::TypeData);
NDO->define(&ClassObject::TypeData);
NDO->define(&ColorObject::TypeData);
NDO->define(&InterpreterObject::TypeData);
NDO->define(&TypeObject::TypeData);
}
static void defineGroups() {
NDO->type_groups.addType(&DictObject::TypeData, {"Primitives"});
NDO->type_groups.addType(&IntObject::TypeData, {"Primitives"});
NDO->type_groups.addType(&LinkObject::TypeData, {"Primitives"});
NDO->type_groups.addType(&ListObject::TypeData, {"Primitives"});
NDO->type_groups.addType(&NullObject::TypeData, {"Primitives"});
NDO->type_groups.addType(&StringObject::TypeData, {"Primitives"});
NDO->type_groups.addType(&BoolObject::TypeData, {"Primitives"});
NDO->type_groups.addType(&FloatObject::TypeData, {"Primitives"});
NDO->type_groups.addType(&EnumObject::TypeData, {"Primitives"});
NDO->type_groups.addType(&ClassObject::TypeData, {"Primitives"});
NDO->type_groups.addType(&ColorObject::TypeData, {"Primitives"});
NDO->type_groups.addType(&InterpreterObject::TypeData, { "scripting" });
}
static bool init(const tp::ModuleManifest*) {
if (!NDO) NDO = new objects_api();
obj::BCgen::init();
MethodObject::Initialize();
defineTypes();
defineGroups();
return true;
}
static void deinit(const tp::ModuleManifest*) {
NullObject::uninit();
MethodObject::UnInitialize();
obj::BCgen::deinit();
assertNoLeaks();
delete NDO;
NDO = nullptr;
}
static tp::ModuleManifest* sModuleDependencies[] = {
// &tp::gModuleCompressor,
&tp::gModuleMath,
&tp::gModuleStrings,
&tp::gModuleTokenizer,
&tp::gModuleConnection,
NULL
};
#include "NewPlacement.hpp"
#include "Tokenizer.hpp"
#include "compiler/function.h"
#include "primitives/boolobject.h"
#include "primitives/classobject.h"
#include "primitives/colorobject.h"
#include "primitives/dictobject.h"
#include "primitives/enumobject.h"
#include "primitives/floatobject.h"
#include "primitives/interpreterobject.h"
#include "primitives/intobject.h"
#include "primitives/linkobject.h"
#include "primitives/listobject.h"
#include "primitives/methodobject.h"
#include "primitives/nullobject.h"
#include "primitives/stringobject.h"
#include "primitives/typeobject.h"
using namespace obj;
using namespace tp;
static void defineTypes() {
NDO->define(&DictObject::TypeData);
NDO->define(&IntObject::TypeData);
NDO->define(&LinkObject::TypeData);
NDO->define(&ListObject::TypeData);
NDO->define(&NullObject::TypeData);
NDO->define(&StringObject::TypeData);
NDO->define(&BoolObject::TypeData);
NDO->define(&FloatObject::TypeData);
NDO->define(&EnumObject::TypeData);
NDO->define(&ClassObject::TypeData);
NDO->define(&ColorObject::TypeData);
NDO->define(&InterpreterObject::TypeData);
NDO->define(&TypeObject::TypeData);
}
static void defineGroups() {
NDO->type_groups.addType(&DictObject::TypeData, { "Primitives" });
NDO->type_groups.addType(&IntObject::TypeData, { "Primitives" });
NDO->type_groups.addType(&LinkObject::TypeData, { "Primitives" });
NDO->type_groups.addType(&ListObject::TypeData, { "Primitives" });
NDO->type_groups.addType(&NullObject::TypeData, { "Primitives" });
NDO->type_groups.addType(&StringObject::TypeData, { "Primitives" });
NDO->type_groups.addType(&BoolObject::TypeData, { "Primitives" });
NDO->type_groups.addType(&FloatObject::TypeData, { "Primitives" });
NDO->type_groups.addType(&EnumObject::TypeData, { "Primitives" });
NDO->type_groups.addType(&ClassObject::TypeData, { "Primitives" });
NDO->type_groups.addType(&ColorObject::TypeData, { "Primitives" });
NDO->type_groups.addType(&InterpreterObject::TypeData, { "scripting" });
}
static bool init(const tp::ModuleManifest*) {
if (!NDO) NDO = new objects_api();
obj::BCgen::init();
MethodObject::Initialize();
defineTypes();
defineGroups();
return true;
}
static void deinit(const tp::ModuleManifest*) {
NullObject::uninit();
MethodObject::UnInitialize();
obj::BCgen::deinit();
assertNoLeaks();
delete NDO;
NDO = nullptr;
}
static tp::ModuleManifest* sModuleDependencies[] = {
// &tp::gModuleCompressor,
&tp::gModuleMath,
&tp::gModuleStrings,
&tp::gModuleTokenizer,
&tp::gModuleConnection,
NULL
};
tp::ModuleManifest obj::gModuleObjects = tp::ModuleManifest("Objects", init, deinit, sModuleDependencies);

View file

@ -1,230 +1,227 @@
#include "NewPlacement.hpp"
#include "core/object.h"
#include "primitives/nullobject.h"
#include "primitives/classobject.h"
#include "primitives/methodobject.h"
#include "interpreter/interpreter.h"
#include "compiler/function.h"
namespace obj {
Object* ObjectMemAllocate(const ObjectType* type);
void ObjectMemDeallocate(Object* in);
objects_api* NDO = NULL;
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() {
delete interp;
}
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);
type->type_methods.init();
}
Object* objects_api::create(const tp::String& name) {
MODULE_SANITY_CHECK(gModuleObjects);
const ObjectType* type = types.get(name);
Object* obj_instance = ObjectMemAllocate(type);
if (!obj_instance) {
return NULL;
}
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 NULL;
}
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, tp::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;
}
tp::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;
}
#ifdef OBJECT_REF_COUNT
ObjectMemHead* mh = NDO_MEMH_FROM_NDO(in);
if (mh->refc > 1) {
mh->refc--;
return;
}
#endif
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);
}
#ifdef OBJECT_REF_COUNT
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;
}
#endif
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;
}
return NULL;
}
#include "NewPlacement.hpp"
#include "core/object.h"
#include "primitives/classobject.h"
#include "primitives/methodobject.h"
#include "primitives/nullobject.h"
#include "compiler/function.h"
#include "interpreter/interpreter.h"
namespace obj {
Object* ObjectMemAllocate(const ObjectType* type);
void ObjectMemDeallocate(Object* in);
objects_api* NDO = NULL;
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() { delete interp; }
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);
type->type_methods.init();
}
Object* objects_api::create(const tp::String& name) {
MODULE_SANITY_CHECK(gModuleObjects);
const ObjectType* type = types.get(name);
Object* obj_instance = ObjectMemAllocate(type);
if (!obj_instance) {
return NULL;
}
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 NULL;
}
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, tp::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;
}
tp::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;
}
#ifdef OBJECT_REF_COUNT
ObjectMemHead* mh = NDO_MEMH_FROM_NDO(in);
if (mh->refc > 1) {
mh->refc--;
return;
}
#endif
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);
}
#ifdef OBJECT_REF_COUNT
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;
}
#endif
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;
}
return NULL;
}
};

View file

@ -1,444 +1,435 @@
#include "NewPlacement.hpp"
#include "core/object.h"
#include "primitives/nullobject.h"
#include "HeapAllocatorGlobal.hpp"
#include <malloc.h>
namespace obj {
ObjectMemHead* bottom = nullptr;
struct ObjectsFileHeader {
char name[10] = {0};
char version[10] = {0};
ObjectsFileHeader(bool default_val = true) {
if (default_val) {
tp::memCopy(&name, "objects", tp::String::Logic::calcLength("objects") + 1);
tp::memCopy(&version, "0", tp::String::Logic::calcLength("0") + 1);
}
}
};
Object* ObjectMemAllocate(const ObjectType* type) {
ObjectMemHead* memh = (ObjectMemHead*) tp::HeapAllocGlobal::allocate(type->size + sizeof(ObjectMemHead));
if (!memh) {
return NULL;
}
memh->down = NULL;
memh->flags = 0;
#ifdef OBJECT_REF_COUNT
memh->refc = (tp::alni) 1;
#endif
if (bottom) {
bottom->down = memh;
}
memh->up = bottom;
bottom = memh;
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;
}
tp::HeapAllocGlobal::deallocate(memh);
}
void logTypeData(const ObjectType* type) {
printf("type - %s\n", type->name);
if (type->base) {
printf("Based on ");
logTypeData(type->base);
}
}
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++;
}
}
}
struct ObjectFileHead {
Object* load_head_adress = 0;
tp::halni refc = 0;
};
tp::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;
}
}
tp::alni& getObjectFlags(Object* in) {
return NDO_MEMH_FROM_NDO(in)->flags;
}
tp::alni objsize_ram_util(Object* self, const ObjectType* type) {
tp::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;
}
tp::alni objects_api::objsize_ram(Object* self) {
return objsize_ram_util(self, self->type);
}
tp::alni objects_api::objsize_ram_recursive_util(Object* self, const ObjectType* type, bool different_object) {
tp::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_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);
}
tp::alni objsize_file_util(Object* self, const ObjectType* type) {
tp::alni out = 0;
if (type->save_size) {
out += type->save_size(self);
}
if (type->base) {
out += objsize_file_util(self, type->base);
}
return out;
}
tp::alni objects_api::objsize_file(Object* self) {
return objsize_file_util(self, self->type);
}
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;
}
tp::alni objects_api::objsize_file_recursive(Object* self) {
clear_object_flags();
return objsize_file_recursive_util(self, self->type);
}
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 write
if (type->save) {
type->save(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;
ndf << tp::String(in->type->name);
// allocate for object file header
ndf.setFreeAddress(ndf.getFreeAddress() + sizeof(ObjectFileHead) + tp::SaveSizeCounter::calc(tp::String(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);
}
}
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 read address
tp::alni parent_file_adress = ndf.getAddress();
// set read address
ndf.setAddress(file_adress);
ObjectFileHead ofh;
ndf >> ofh;
tp::String type_name;
ndf >> type_name;
const ObjectType* object_type = NDO->types.get(type_name);
Object* out = ObjectMemAllocate(object_type);
if (!out) {
return NULL;
}
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, tp::String path, bool compressed) {
ArchiverOut ndf(path.read());
if (!ndf.isOpened()) {
return false;
}
clear_object_flags();
// save version info
ObjectsFileHeader header;
ndf << header;
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;
}
Object* objects_api::load(tp::String path) {
/*
auto temp_file_name = path + ".unz";
bool unz_res = tp::decompressF2F(path.cstr(), temp_file_name.cstr());
if (!unz_res) {
return NULL;
}
File ndf(temp_file_name.cstr(), tp::osfile_openflags::LOAD);
*/
ArchiverIn ndf(path.read());
if (!ndf.isOpened()) {
return NULL;
}
// check for compatibility
ObjectsFileHeader current_header;
ObjectsFileHeader loaded_header(false);
ndf >> loaded_header;
if (!tp::memEqual(&current_header, &loaded_header, sizeof(ObjectsFileHeader))) {
return NULL;
}
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 == NULL) {
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++;
}
#include "NewPlacement.hpp"
#include "core/object.h"
#include "primitives/nullobject.h"
#include "HeapAllocatorGlobal.hpp"
#include <malloc.h>
namespace obj {
ObjectMemHead* bottom = nullptr;
struct ObjectsFileHeader {
char name[10] = { 0 };
char version[10] = { 0 };
ObjectsFileHeader(bool default_val = true) {
if (default_val) {
tp::memCopy(&name, "objects", tp::String::Logic::calcLength("objects") + 1);
tp::memCopy(&version, "0", tp::String::Logic::calcLength("0") + 1);
}
}
};
Object* ObjectMemAllocate(const ObjectType* type) {
ObjectMemHead* memh = (ObjectMemHead*) tp::HeapAllocGlobal::allocate(type->size + sizeof(ObjectMemHead));
if (!memh) {
return NULL;
}
memh->down = NULL;
memh->flags = 0;
#ifdef OBJECT_REF_COUNT
memh->refc = (tp::alni) 1;
#endif
if (bottom) {
bottom->down = memh;
}
memh->up = bottom;
bottom = memh;
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;
}
tp::HeapAllocGlobal::deallocate(memh);
}
void logTypeData(const ObjectType* type) {
printf("type - %s\n", type->name);
if (type->base) {
printf("Based on ");
logTypeData(type->base);
}
}
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++;
}
}
}
struct ObjectFileHead {
Object* load_head_adress = 0;
tp::halni refc = 0;
};
tp::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;
}
}
tp::alni& getObjectFlags(Object* in) { return NDO_MEMH_FROM_NDO(in)->flags; }
tp::alni objsize_ram_util(Object* self, const ObjectType* type) {
tp::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;
}
tp::alni objects_api::objsize_ram(Object* self) { return objsize_ram_util(self, self->type); }
tp::alni objects_api::objsize_ram_recursive_util(Object* self, const ObjectType* type, bool different_object) {
tp::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_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);
}
tp::alni objsize_file_util(Object* self, const ObjectType* type) {
tp::alni out = 0;
if (type->save_size) {
out += type->save_size(self);
}
if (type->base) {
out += objsize_file_util(self, type->base);
}
return out;
}
tp::alni objects_api::objsize_file(Object* self) { return objsize_file_util(self, self->type); }
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;
}
tp::alni objects_api::objsize_file_recursive(Object* self) {
clear_object_flags();
return objsize_file_recursive_util(self, self->type);
}
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 write
if (type->save) {
type->save(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;
ndf << tp::String(in->type->name);
// allocate for object file header
ndf.setFreeAddress(ndf.getFreeAddress() + sizeof(ObjectFileHead) + tp::SaveSizeCounter::calc(tp::String(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);
}
}
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 read address
tp::alni parent_file_adress = ndf.getAddress();
// set read address
ndf.setAddress(file_adress);
ObjectFileHead ofh;
ndf >> ofh;
tp::String type_name;
ndf >> type_name;
const ObjectType* object_type = NDO->types.get(type_name);
Object* out = ObjectMemAllocate(object_type);
if (!out) {
return NULL;
}
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, tp::String path, bool compressed) {
ArchiverOut ndf(path.read());
if (!ndf.isOpened()) {
return false;
}
clear_object_flags();
// save version info
ObjectsFileHeader header;
ndf << header;
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;
}
Object* objects_api::load(tp::String path) {
/*
auto temp_file_name = path + ".unz";
bool unz_res = tp::decompressF2F(path.cstr(), temp_file_name.cstr());
if (!unz_res) {
return NULL;
}
File ndf(temp_file_name.cstr(), tp::osfile_openflags::LOAD);
*/
ArchiverIn ndf(path.read());
if (!ndf.isOpened()) {
return NULL;
}
// check for compatibility
ObjectsFileHeader current_header;
ObjectsFileHeader loaded_header(false);
ndf >> loaded_header;
if (!tp::memEqual(&current_header, &loaded_header, sizeof(ObjectsFileHeader))) {
return NULL;
}
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 == NULL) {
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++;
}
};

View file

@ -1,268 +1,255 @@
#include "NewPlacement.hpp"
#include "HeapAllocatorGlobal.hpp"
#include "core/scriptsection.h"
using namespace obj;
ScriptSection* gScriptSection = NULL;
struct script_data_head {
tp::alni refc = 0;
tp::alni store_adress = 0;
};
void set_script_head_store_adress(Script* in, tp::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;
}
Script* ScriptSection::createScript() {
auto sdhead = (script_data_head*)tp::HeapAllocGlobal::allocate(sizeof(script_data_head) + sizeof(Script));
auto out = (Script*)(sdhead + 1);
if (!sdhead) {
return NULL;
}
sdhead->refc = 1;
sdhead->store_adress = -1;
mScripts.pushBack(out);
new (out) Script();
out->mReadable = obj::StringObject::create("");
obj::NDO->refinc(out->mReadable);
return out;
}
void ScriptSection::delete_script(Script* script) {
script->~Script();
obj::NDO->destroy(script->mReadable);
tp::HeapAllocGlobal::deallocate((((script_data_head*)script) - 1));
}
void ScriptSection::reference_script(Script* script) {
(((script_data_head*)script) - 1)->refc++;
}
void ScriptSection::abandonScript(Script* script) {
if ((((script_data_head*)script) - 1)->refc > 1) {
(((script_data_head*)script) - 1)->refc--;
}
else {
// ISSUE : on delete list structure is outdated
// FIXME : use pool alloc with ref count
// forwarding to global destruction
//delete_script(script);
}
}
void ScriptSection::changeScript(Script** current_script, Script** new_script) {
abandonScript(*current_script);
reference_script(*new_script);
*current_script = *new_script;
}
tp::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;
size += 5; // header
size += sizeof(tp::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
for (auto const_obj : iter->mBytecode.mConstants) {
size += sizeof(tp::alni); // constant object addres
}
// instructions
size += tp::SaveSizeCounter::calc(iter->mBytecode.mInstructions);
}
size += sizeof(tp::alni); // objects mem offset
size += 5; // header
return size;
}
void ScriptSection::save_script_table_to_file(ScriptSection* self, ArchiverOut& file) {
// header
file.writeBytes("/scr/", 5);
// scripts length
tp::alni scripts_count = self->mScripts.length();
file << scripts_count;
for (auto iter : self->mScripts) {
// scripts string obj ref
auto obj_addres = obj::NDO->save(file, iter->mReadable);
file << obj_addres;
// constants length
tp::alni consts_count = iter->mBytecode.mConstants.size();
file << consts_count;
for (auto const_obj : iter->mBytecode.mConstants) {
// constant object addres
auto obj_addres = obj::NDO->save(file, const_obj.data());
file << obj_addres;
}
// mInstructions
file << iter->mBytecode.mInstructions;
}
// header
file.writeBytes("/scr/", 5);
tp::alni objects_mem_offset = file.getFreeAddress();
file << objects_mem_offset;
}
void load_constants(ScriptSection* self, ArchiverIn& file, tp::alni start_addr) {
auto addres = file.getAddress();
file.setAddress(start_addr);
file.setAddress( start_addr + 5); // header
tp::alni scripts_count;
file >> scripts_count;
for (tp::alni i = 0; i < scripts_count; i++) {
auto script = self->get_scritp_from_file_adress(file.getAddress());
// script text
tp::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
for (auto const_obj : script->mBytecode.mConstants) {
tp::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(addres);
}
void ScriptSection::load_script_table_from_file(ScriptSection* self, ArchiverIn& file) {
for (auto iter : self->mScripts) {
set_script_head_store_adress(iter.data(), -1);
}
auto section_start_addr = file.getAddress();
// header
file.setAddress(file.getAddress() + 5);
// scripts length
tp::alni scripts_count;
file >> scripts_count;
for (tp::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));
// constants length
tp::alni consts_count;
file >> consts_count;
new_script->mBytecode.mConstants.reserve(consts_count);
for (tp::alni j = 0; j < consts_count; j++) {
// constant object addres
tp::alni consts_addr;
file >> consts_addr;
// skiping
//new_script->mBytecode.mConstants[j] = obj::NDO->load(file, consts_addr);
}
// mInstructions
file >> new_script->mBytecode.mInstructions;
}
load_constants(self, file, section_start_addr);
// header
file.setAddress(file.getAddress() + 5);
tp::alni objects_mem_offset;
file >> objects_mem_offset;
file.setAddress(objects_mem_offset);
}
Script* ScriptSection::get_scritp_from_file_adress(tp::alni file_adress) {
for (auto iter : mScripts) {
if (get_script_head_store_adress(iter.data()) == file_adress) {
return iter.data();
}
}
return NULL;
}
ScriptSection::~ScriptSection() {
for (auto iter : mScripts) {
delete_script(iter.data());
}
}
obj::save_load_callbacks ScriptSection::slcb_script_section = {
.self = gScriptSection,
.pre_save = (obj::pre_save_callback*)ScriptSection::save_script_table_to_file,
.size = (obj::slcb_size_callback*)ScriptSection::save_script_table_to_file_size,
.pre_load = (obj::pre_load_callback*)ScriptSection::load_script_table_from_file,
.post_save = NULL,
.post_load = NULL,
};
void ScriptSection::initialize() {
ASSERT(!gScriptSection);
gScriptSection = new ScriptSection();
ASSERT(obj::NDO && "Forgot to initialize objects?");
slcb_script_section.self = gScriptSection;
obj::NDO->add_sl_callbacks(&slcb_script_section);
}
void ScriptSection::uninitialize() {
ASSERT(gScriptSection);
delete gScriptSection;
gScriptSection = nullptr;
}
ScriptSection* ScriptSection::globalHandle() {
return gScriptSection;
}
#include "HeapAllocatorGlobal.hpp"
#include "NewPlacement.hpp"
#include "core/scriptsection.h"
using namespace obj;
ScriptSection* gScriptSection = NULL;
struct script_data_head {
tp::alni refc = 0;
tp::alni store_adress = 0;
};
void set_script_head_store_adress(Script* in, tp::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; }
Script* ScriptSection::createScript() {
auto sdhead = (script_data_head*) tp::HeapAllocGlobal::allocate(sizeof(script_data_head) + sizeof(Script));
auto out = (Script*) (sdhead + 1);
if (!sdhead) {
return NULL;
}
sdhead->refc = 1;
sdhead->store_adress = -1;
mScripts.pushBack(out);
new (out) Script();
out->mReadable = obj::StringObject::create("");
obj::NDO->refinc(out->mReadable);
return out;
}
void ScriptSection::delete_script(Script* script) {
script->~Script();
obj::NDO->destroy(script->mReadable);
tp::HeapAllocGlobal::deallocate((((script_data_head*) script) - 1));
}
void ScriptSection::reference_script(Script* script) { (((script_data_head*) script) - 1)->refc++; }
void ScriptSection::abandonScript(Script* script) {
if ((((script_data_head*) script) - 1)->refc > 1) {
(((script_data_head*) script) - 1)->refc--;
} else {
// ISSUE : on delete list structure is outdated
// FIXME : use pool alloc with ref count
// forwarding to global destruction
// delete_script(script);
}
}
void ScriptSection::changeScript(Script** current_script, Script** new_script) {
abandonScript(*current_script);
reference_script(*new_script);
*current_script = *new_script;
}
tp::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;
size += 5; // header
size += sizeof(tp::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
for (auto const_obj : iter->mBytecode.mConstants) {
size += sizeof(tp::alni); // constant object addres
}
// instructions
size += tp::SaveSizeCounter::calc(iter->mBytecode.mInstructions);
}
size += sizeof(tp::alni); // objects mem offset
size += 5; // header
return size;
}
void ScriptSection::save_script_table_to_file(ScriptSection* self, ArchiverOut& file) {
// header
file.writeBytes("/scr/", 5);
// scripts length
tp::alni scripts_count = self->mScripts.length();
file << scripts_count;
for (auto iter : self->mScripts) {
// scripts string obj ref
auto obj_addres = obj::NDO->save(file, iter->mReadable);
file << obj_addres;
// constants length
tp::alni consts_count = iter->mBytecode.mConstants.size();
file << consts_count;
for (auto const_obj : iter->mBytecode.mConstants) {
// constant object addres
auto obj_addres = obj::NDO->save(file, const_obj.data());
file << obj_addres;
}
// mInstructions
file << iter->mBytecode.mInstructions;
}
// header
file.writeBytes("/scr/", 5);
tp::alni objects_mem_offset = file.getFreeAddress();
file << objects_mem_offset;
}
void load_constants(ScriptSection* self, ArchiverIn& file, tp::alni start_addr) {
auto addres = file.getAddress();
file.setAddress(start_addr);
file.setAddress(start_addr + 5); // header
tp::alni scripts_count;
file >> scripts_count;
for (tp::alni i = 0; i < scripts_count; i++) {
auto script = self->get_scritp_from_file_adress(file.getAddress());
// script text
tp::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
for (auto const_obj : script->mBytecode.mConstants) {
tp::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(addres);
}
void ScriptSection::load_script_table_from_file(ScriptSection* self, ArchiverIn& file) {
for (auto iter : self->mScripts) {
set_script_head_store_adress(iter.data(), -1);
}
auto section_start_addr = file.getAddress();
// header
file.setAddress(file.getAddress() + 5);
// scripts length
tp::alni scripts_count;
file >> scripts_count;
for (tp::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));
// constants length
tp::alni consts_count;
file >> consts_count;
new_script->mBytecode.mConstants.reserve(consts_count);
for (tp::alni j = 0; j < consts_count; j++) {
// constant object addres
tp::alni consts_addr;
file >> consts_addr;
// skiping
// new_script->mBytecode.mConstants[j] = obj::NDO->load(file, consts_addr);
}
// mInstructions
file >> new_script->mBytecode.mInstructions;
}
load_constants(self, file, section_start_addr);
// header
file.setAddress(file.getAddress() + 5);
tp::alni objects_mem_offset;
file >> objects_mem_offset;
file.setAddress(objects_mem_offset);
}
Script* ScriptSection::get_scritp_from_file_adress(tp::alni file_adress) {
for (auto iter : mScripts) {
if (get_script_head_store_adress(iter.data()) == file_adress) {
return iter.data();
}
}
return NULL;
}
ScriptSection::~ScriptSection() {
for (auto iter : mScripts) {
delete_script(iter.data());
}
}
obj::save_load_callbacks ScriptSection::slcb_script_section = {
.self = gScriptSection,
.pre_save = (obj::pre_save_callback*) ScriptSection::save_script_table_to_file,
.size = (obj::slcb_size_callback*) ScriptSection::save_script_table_to_file_size,
.pre_load = (obj::pre_load_callback*) ScriptSection::load_script_table_from_file,
.post_save = NULL,
.post_load = NULL,
};
void ScriptSection::initialize() {
ASSERT(!gScriptSection);
gScriptSection = new ScriptSection();
ASSERT(obj::NDO && "Forgot to initialize objects?");
slcb_script_section.self = gScriptSection;
obj::NDO->add_sl_callbacks(&slcb_script_section);
}
void ScriptSection::uninitialize() {
ASSERT(gScriptSection);
delete gScriptSection;
gScriptSection = nullptr;
}
ScriptSection* ScriptSection::globalHandle() { return gScriptSection; }

View file

@ -1,81 +1,83 @@
#include "NewPlacement.hpp"
#include "core/typegroups.h"
#include "core/object.h"
using namespace obj;
obj::TypeGroups::TypeGroups() : is_group(true) {
new (&childs) Dict();
}
obj::TypeGroups::TypeGroups(bool is_group) : is_group(is_group) {
if (is_group) {
new (&childs) Dict();
} else {
type = NULL;
}
}
bool obj::TypeGroups::isGroup() { return is_group; }
obj::TypeGroups::Dict* obj::TypeGroups::getChilds() {
DEBUG_ASSERT(is_group);
return &childs;
}
void obj::TypeGroups::setType(ObjectType* type) {
DEBUG_ASSERT(!is_group);
this->type = type;
}
void obj::TypeGroups::addType(ObjectType* type, tp::InitialierList<const char*> path, tp::alni cur_dir_idx) {
DEBUG_ASSERT(is_group);
tp::alni dir_len = (tp::alni) path.size();
if (dir_len == cur_dir_idx) {
TypeGroups* type_ref = new TypeGroups(false);
type_ref->setType(type);
childs.put(type->name, type_ref);
return;
}
TypeGroups* group = NULL;
tp::alni index = 0;
for (auto dir : path) {
if (index != cur_dir_idx) {
index++;
continue;
}
auto child_idx = childs.presents(dir);
if (child_idx) {
group = childs.getSlotVal(child_idx);
} else {
group = new TypeGroups(true);
childs.put(dir, group);
}
group->addType(type, path, cur_dir_idx + 1);
break;
}
}
const obj::ObjectType* obj::TypeGroups::getType() {
DEBUG_ASSERT(!is_group);
return type;
}
obj::TypeGroups::~TypeGroups() {
if (is_group) {
for (auto& child : childs) {
delete child->val;
}
childs.~Map();
}
#include "NewPlacement.hpp"
#include "core/typegroups.h"
#include "core/object.h"
using namespace obj;
obj::TypeGroups::TypeGroups() :
is_group(true) {
new (&childs) Dict();
}
obj::TypeGroups::TypeGroups(bool is_group) :
is_group(is_group) {
if (is_group) {
new (&childs) Dict();
} else {
type = NULL;
}
}
bool obj::TypeGroups::isGroup() { return is_group; }
obj::TypeGroups::Dict* obj::TypeGroups::getChilds() {
DEBUG_ASSERT(is_group);
return &childs;
}
void obj::TypeGroups::setType(ObjectType* type) {
DEBUG_ASSERT(!is_group);
this->type = type;
}
void obj::TypeGroups::addType(ObjectType* type, tp::InitialierList<const char*> path, tp::alni cur_dir_idx) {
DEBUG_ASSERT(is_group);
tp::alni dir_len = (tp::alni) path.size();
if (dir_len == cur_dir_idx) {
TypeGroups* type_ref = new TypeGroups(false);
type_ref->setType(type);
childs.put(type->name, type_ref);
return;
}
TypeGroups* group = NULL;
tp::alni index = 0;
for (auto dir : path) {
if (index != cur_dir_idx) {
index++;
continue;
}
auto child_idx = childs.presents(dir);
if (child_idx) {
group = childs.getSlotVal(child_idx);
} else {
group = new TypeGroups(true);
childs.put(dir, group);
}
group->addType(type, path, cur_dir_idx + 1);
break;
}
}
const obj::ObjectType* obj::TypeGroups::getType() {
DEBUG_ASSERT(!is_group);
return type;
}
obj::TypeGroups::~TypeGroups() {
if (is_group) {
for (auto& child : childs) {
delete child->val;
}
childs.~Map();
}
}

View file

@ -1,138 +1,134 @@
#include "NewPlacement.hpp"
#include "core/typemethods.h"
#include "primitives/nullobject.h"
#include "primitives/typeobject.h"
#include "primitives/floatobject.h"
#include "interpreter/interpreter.h"
using namespace obj;
TypeMethod obj::gDefaultTypeMethods[] = {
{
.nameid = "type",
.descr = "retrieves typeobject",
.exec = [](const TypeMethod* tm) {
tm->ret.obj = TypeObject::create(tm->self->type);
},
.ret = { "typeobject", NULL },
},
{
.nameid = "to_str",
.descr = "converts to string",
.exec = [](const TypeMethod* tm) {
if (tm->self->type->convesions && tm->self->type->convesions->to_string) {
tm->ret.obj = StringObject::create(NDO->toString(tm->self));
}
},
.ret = { "string object", NULL },
},
{
.nameid = "to_float",
.descr = "converts to float",
.exec = [](const TypeMethod* tm) {
if (tm->self->type->convesions && tm->self->type->convesions->to_float) {
tm->ret.obj = FloatObject::create(NDO->toFloat(tm->self));
}
},
.ret = { "string object", NULL },
},
};
tp::int2 TypeMethods::presents(tp::String id) const {
for (tp::int2 idx = 0; idx < mNMethods; idx++) {
if (id == methods[idx]->nameid) {
return idx;
}
}
tp::int2 idx = 0;
for (auto& tm : gDefaultTypeMethods) {
if (id == tm.nameid) {
return { tp::int2(idx + MAX_TYPE_METHODS) };
}
idx++;
}
return -1;
}
TypeMethods::LookupKey TypeMethods::presents(const ObjectType* type, tp::String id) {
tp::int2 depth = 0;
tp::int2 idx = 0;
for (auto iter_type = type; iter_type; iter_type = iter_type->base) {
idx = iter_type->type_methods.presents(id);
if (idx != -1) {
break;
}
depth++;
}
return { idx, depth};
}
const TypeMethod* TypeMethods::getMethod(tp::int2 key) const {
if (key < MAX_TYPE_METHODS) {
return methods[key];
}
return &gDefaultTypeMethods[key - MAX_TYPE_METHODS];
}
const TypeMethod* TypeMethods::getMethod(const ObjectType* type, LookupKey key) {
auto type_iter = type;
for (auto idx = 0; idx < key.type_depth; idx++) {
type_iter = type_iter->base;
}
return type_iter->type_methods.getMethod(key.key);
}
void TypeMethods::init() {
while (methods[mNMethods]) {
mNMethods++;
}
for (tp::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;
}
void TypeMethod::operator()(Interpreter* interp) const{
for (auto i = 1; i <= mNargs; i++) {
args[mNargs - i].obj = interp->mOperandsStack.getOperand();
//NDO->refinc(args[i].obj);
ASSERT(args[mNargs - i].obj && "expected an argument");
}
ASSERT(!interp->mOperandsStack.getOperand() && "args remained");
interp->mOperandsStack.getOperand();
self = interp->mLastParent;
exec(this);
if (ret.obj) {
interp->mOperandsStack.push(ret.obj);
interp->mScopeStack.addTempReturn(ret.obj);
}
else {
interp->mOperandsStack.push(NDO_NULL_REF);
}
}
void TypeMethod::init() {
while (args[mNargs].descr) {
mNargs++;
}
#include "NewPlacement.hpp"
#include "core/typemethods.h"
#include "primitives/floatobject.h"
#include "primitives/nullobject.h"
#include "primitives/typeobject.h"
#include "interpreter/interpreter.h"
using namespace obj;
TypeMethod obj::gDefaultTypeMethods[] = {
{
.nameid = "type",
.descr = "retrieves typeobject",
.exec = [](const TypeMethod* tm) { tm->ret.obj = TypeObject::create(tm->self->type); },
.ret = { "typeobject", NULL },
},
{
.nameid = "to_str",
.descr = "converts to string",
.exec =
[](const TypeMethod* tm) {
if (tm->self->type->convesions && tm->self->type->convesions->to_string) {
tm->ret.obj = StringObject::create(NDO->toString(tm->self));
}
},
.ret = { "string object", NULL },
},
{
.nameid = "to_float",
.descr = "converts to float",
.exec =
[](const TypeMethod* tm) {
if (tm->self->type->convesions && tm->self->type->convesions->to_float) {
tm->ret.obj = FloatObject::create(NDO->toFloat(tm->self));
}
},
.ret = { "string object", NULL },
},
};
tp::int2 TypeMethods::presents(tp::String id) const {
for (tp::int2 idx = 0; idx < mNMethods; idx++) {
if (id == methods[idx]->nameid) {
return idx;
}
}
tp::int2 idx = 0;
for (auto& tm : gDefaultTypeMethods) {
if (id == tm.nameid) {
return { tp::int2(idx + MAX_TYPE_METHODS) };
}
idx++;
}
return -1;
}
TypeMethods::LookupKey TypeMethods::presents(const ObjectType* type, tp::String id) {
tp::int2 depth = 0;
tp::int2 idx = 0;
for (auto iter_type = type; iter_type; iter_type = iter_type->base) {
idx = iter_type->type_methods.presents(id);
if (idx != -1) {
break;
}
depth++;
}
return { idx, depth };
}
const TypeMethod* TypeMethods::getMethod(tp::int2 key) const {
if (key < MAX_TYPE_METHODS) {
return methods[key];
}
return &gDefaultTypeMethods[key - MAX_TYPE_METHODS];
}
const TypeMethod* TypeMethods::getMethod(const ObjectType* type, LookupKey key) {
auto type_iter = type;
for (auto idx = 0; idx < key.type_depth; idx++) {
type_iter = type_iter->base;
}
return type_iter->type_methods.getMethod(key.key);
}
void TypeMethods::init() {
while (methods[mNMethods]) {
mNMethods++;
}
for (tp::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; }
void TypeMethod::operator()(Interpreter* interp) const {
for (auto i = 1; i <= mNargs; i++) {
args[mNargs - i].obj = interp->mOperandsStack.getOperand();
// NDO->refinc(args[i].obj);
ASSERT(args[mNargs - i].obj && "expected an argument");
}
ASSERT(!interp->mOperandsStack.getOperand() && "args remained");
interp->mOperandsStack.getOperand();
self = interp->mLastParent;
exec(this);
if (ret.obj) {
interp->mOperandsStack.push(ret.obj);
interp->mScopeStack.addTempReturn(ret.obj);
} else {
interp->mOperandsStack.push(NDO_NULL_REF);
}
}
void TypeMethod::init() {
while (args[mNargs].descr) {
mNargs++;
}
}