Method object refactor

This commit is contained in:
IlyaShurupov 2024-03-25 13:57:31 +03:00 committed by Ilya Shurupov
parent 714bdaef12
commit 715175085e
25 changed files with 420 additions and 529 deletions

View file

@ -12,10 +12,7 @@ using namespace obj;
ObjectsContext* obj::gObjectsContext = nullptr;
ObjectsContext::ObjectsContext() {
memSetVal(sl_callbacks, SAVE_LOAD_MAX_CALLBACK_SLOTS * sizeof(save_load_callbacks*), 0);
interp = new Interpreter();
}
ObjectsContext::ObjectsContext() { interp = new Interpreter(); }
ObjectsContext::~ObjectsContext() { delete interp; }
@ -24,9 +21,12 @@ void objects_api::initialize() {
gObjectsContext = new ObjectsContext();
gObjectsContext->nullObject = create<NullObject>();
objects_api::increaseReferenceCount(gObjectsContext->nullObject);
}
void objects_api::finalize() {
destroy(gObjectsContext->nullObject);
assertNoLeaks();
ASSERT(gObjectsContext)

View file

@ -327,32 +327,8 @@ bool objects_api::save(Object* in, const std::string& path, bool compressed) {
ndf.setFreeAddress(ndf.getAddress());
// pre allocate
for (alni i = 0; i < SAVE_LOAD_MAX_CALLBACK_SLOTS; i++) {
if (gObjectsContext->sl_callbacks[i]) {
DEBUG_ASSERT(gObjectsContext->sl_callbacks[i]->size);
ndf.setFreeAddress(
ndf.getFreeAddress() + gObjectsContext->sl_callbacks[i]->size(gObjectsContext->sl_callbacks[i]->self, ndf)
);
}
}
// pre-save
for (alni i = 0; i < SAVE_LOAD_MAX_CALLBACK_SLOTS; i++) {
if (gObjectsContext->sl_callbacks[i] && gObjectsContext->sl_callbacks[i]->pre_save) {
gObjectsContext->sl_callbacks[i]->pre_save(gObjectsContext->sl_callbacks[i]->self, ndf);
}
}
save(ndf, in);
// post-save
for (alni i = 0; i < SAVE_LOAD_MAX_CALLBACK_SLOTS; i++) {
if (gObjectsContext->sl_callbacks[i] && gObjectsContext->sl_callbacks[i]->post_save) {
gObjectsContext->sl_callbacks[i]->post_save(gObjectsContext->sl_callbacks[i]->self, ndf);
}
}
// TODO : add compression
/*
if (compressed) {
@ -404,22 +380,8 @@ Object* objects_api::load(const std::string& path) {
ndf.setAddress(sizeof(ObjectsFileHeader));
// preload
for (alni i = 0; i < SAVE_LOAD_MAX_CALLBACK_SLOTS; i++) {
if (gObjectsContext->sl_callbacks[i] && gObjectsContext->sl_callbacks[i]->pre_load) {
gObjectsContext->sl_callbacks[i]->pre_load(gObjectsContext->sl_callbacks[i]->self, ndf);
}
}
Object* out = load(ndf, ndf.getAddress());
// post
for (alni i = 0; i < SAVE_LOAD_MAX_CALLBACK_SLOTS; i++) {
if (gObjectsContext->sl_callbacks[i] && gObjectsContext->sl_callbacks[i]->post_save) {
gObjectsContext->sl_callbacks[i]->post_load(gObjectsContext->sl_callbacks[i]->self, ndf);
}
}
free(loaded_file);
/*
@ -431,9 +393,4 @@ Object* objects_api::load(const std::string& path) {
*/
return out;
}
void objects_api::add_sl_callbacks(save_load_callbacks* in) {
gObjectsContext->sl_callbacks[gObjectsContext->sl_callbacks_load_idx] = in;
gObjectsContext->sl_callbacks_load_idx++;
}
}

View file

@ -1,7 +1,6 @@
#include "compiler/Functions.hpp"
#include "primitives/PrimitiveObjects.hpp"
#include "core/ScriptSection.hpp"
using namespace tp;
using namespace obj;
@ -20,6 +19,7 @@ static void defineTypes() {
objects_api::define(&ColorObject::TypeData);
objects_api::define(&InterpreterObject::TypeData);
objects_api::define(&TypeObject::TypeData);
objects_api::define(&BytecodeObject::TypeData);
objects_api::define(&MethodObject::TypeData);
}
@ -42,19 +42,13 @@ static void defineGroups() {
static bool init(const ModuleManifest*) {
objects_api::initialize();
ScriptSection::initialize();
defineTypes();
defineGroups();
return true;
}
static void deinit(const ModuleManifest*) {
ScriptSection::uninitialize();
objects_api::finalize();
}
static void deinit(const ModuleManifest*) { objects_api::finalize(); }
static ModuleManifest* sModuleDependencies[] = { nullptr };

View file

@ -1,251 +0,0 @@
#include "core/ScriptSection.hpp"
using namespace tp;
using namespace obj;
ScriptSection* gScriptSection = nullptr;
struct script_data_head {
alni refc = 0;
alni store_adress = 0;
};
void set_script_head_store_adress(Script* in, alni address) { ((script_data_head*) in - 1)->store_adress = address; }
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));
auto out = (Script*) (sdhead + 1);
if (!sdhead) {
return nullptr;
}
sdhead->refc = 1;
sdhead->store_adress = -1;
mScripts.pushBack(out);
new (out) Script();
out->mReadable = obj::StringObject::create("");
objects_api::increaseReferenceCount(out->mReadable);
return out;
}
void ScriptSection::delete_script(Script* script) {
script->~Script();
objects_api::destroy(script->mReadable);
free((((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;
}
alni ScriptSection::get_script_file_adress(Script* in) { return get_script_head_store_adress(in); }
alni ScriptSection::save_script_table_to_file_size(ScriptSection* self, ArchiverOut& file) {
alni size = 0;
size += 5; // header
size += sizeof(alni); // scripts length
for (auto iter : self->mScripts) {
set_script_head_store_adress(iter.data(), file.getAddress() + size);
size += sizeof(alni); // scripts string obj ref
size += sizeof(alni); // constants length
for (auto const_obj : iter->mBytecode.mConstants) {
size += sizeof(alni); // constant object addres
}
// instructions
size += SaveSizeCounter::calc(iter->mBytecode.mInstructions);
}
size += sizeof(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
alni scripts_count = self->mScripts.length();
file << scripts_count;
for (auto iter : self->mScripts) {
// scripts string obj ref
auto obj_addres = objects_api::save(file, iter->mReadable);
file << obj_addres;
// constants length
alni consts_count = iter->mBytecode.mConstants.size();
file << consts_count;
for (auto const_obj : iter->mBytecode.mConstants) {
// constant object addres
auto obj_addres = objects_api::save(file, const_obj.data());
file << obj_addres;
}
// mInstructions
file << iter->mBytecode.mInstructions;
}
// header
file.writeBytes("/scr/", 5);
alni objects_mem_offset = file.getFreeAddress();
file << objects_mem_offset;
}
void load_constants(ScriptSection* self, ArchiverIn& file, alni start_addr) {
auto addres = file.getAddress();
file.setAddress(start_addr);
file.setAddress(start_addr + 5); // header
alni scripts_count;
file >> scripts_count;
for (alni i = 0; i < scripts_count; i++) {
auto script = self->get_scritp_from_file_adress(file.getAddress());
// script text
alni str_addr;
file >> str_addr;
objects_api::destroy(script->mReadable); // we already have string object in the script when creating script
script->mReadable = objects_api::cast<StringObject>(objects_api::load(file, str_addr));
file.setAddress(file.getAddress() + sizeof(alni)); // constants length
for (auto const_obj : script->mBytecode.mConstants) {
alni consts_addr;
file >> consts_addr;
const_obj.data() = objects_api::load(file, consts_addr);
}
// instructions
file.setAddress(file.getAddress() + 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
alni scripts_count;
file >> scripts_count;
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(alni));
// constants length
alni consts_count;
file >> consts_count;
new_script->mBytecode.mConstants.reserve(consts_count);
for (alni j = 0; j < consts_count; j++) {
// constant object addres
alni consts_addr;
file >> consts_addr;
// skiping
// new_script->mBytecode.mConstants[j] = objects_api::load(file, consts_addr);
}
// mInstructions
file >> new_script->mBytecode.mInstructions;
}
load_constants(self, file, section_start_addr);
// header
file.setAddress(file.getAddress() + 5);
alni objects_mem_offset;
file >> objects_mem_offset;
file.setAddress(objects_mem_offset);
}
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();
}
}
return nullptr;
}
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 = nullptr,
.post_load = nullptr,
};
void ScriptSection::initialize() {
ASSERT(!gScriptSection);
gScriptSection = new ScriptSection();
slcb_script_section.self = gScriptSection;
objects_api::add_sl_callbacks(&slcb_script_section);
}
void ScriptSection::uninitialize() {
ASSERT(gScriptSection);
delete gScriptSection;
gScriptSection = nullptr;
}
ScriptSection* ScriptSection::globalHandle() { return gScriptSection; }

View file

@ -122,7 +122,7 @@ void TypeMethod::operator()(Interpreter* interp) const {
interp->mOperandsStack.push(ret.obj);
interp->mScopeStack.addTempReturn(ret.obj);
} else {
interp->mOperandsStack.push(NDO_NULL_REF);
interp->mOperandsStack.push(objects_api::getNullReferenced());
}
}