From 394cc689506a6ab1d54f8dcb0c91500a995887ad Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Thu, 28 Jun 2018 21:13:26 +0200 Subject: [PATCH] [DEV] rework Class ClassMethode --- lutin_rabbit-core.py | 8 +- rabbit/{sqclass.cpp => Class.cpp} | 127 ++++++------------------ rabbit/Class.hpp | 75 ++++++++++++++ rabbit/ClassMember.cpp | 9 ++ rabbit/ClassMember.hpp | 37 +++++++ rabbit/Instance.cpp | 66 +++++++++++++ rabbit/Instance.hpp | 87 ++++++++++++++++ rabbit/ObjectPtr.cpp | 4 +- rabbit/ObjectPtr.hpp | 4 +- rabbit/ObjectValue.hpp | 4 +- rabbit/VirtualMachine.cpp | 11 ++- rabbit/VirtualMachine.hpp | 2 +- rabbit/sqapi.cpp | 15 +-- rabbit/sqbaselib.cpp | 2 +- rabbit/sqclass.hpp | 158 ------------------------------ rabbit/sqclosure.hpp | 6 +- rabbit/sqconfig.hpp | 4 +- rabbit/sqobject.cpp | 2 +- rabbit/sqstate.cpp | 2 +- 19 files changed, 338 insertions(+), 285 deletions(-) rename rabbit/{sqclass.cpp => Class.cpp} (52%) create mode 100644 rabbit/Class.hpp create mode 100644 rabbit/ClassMember.cpp create mode 100644 rabbit/ClassMember.hpp create mode 100644 rabbit/Instance.cpp create mode 100644 rabbit/Instance.hpp delete mode 100644 rabbit/sqclass.hpp diff --git a/lutin_rabbit-core.py b/lutin_rabbit-core.py index 53fc448..84db1d6 100644 --- a/lutin_rabbit-core.py +++ b/lutin_rabbit-core.py @@ -31,7 +31,9 @@ def configure(target, my_module): 'rabbit/sqbaselib.cpp', 'rabbit/sqapi.cpp', 'rabbit/sqlexer.cpp', - 'rabbit/sqclass.cpp', + 'rabbit/Class.cpp', + 'rabbit/ClassMember.cpp', + 'rabbit/Instance.cpp', 'rabbit/AutoDec.cpp', 'rabbit/VirtualMachine.cpp', 'rabbit/sqtable.cpp', @@ -62,7 +64,9 @@ def configure(target, my_module): 'etk-base', ]) my_module.add_header_file([ - 'rabbit/sqclass.hpp', + 'rabbit/Class.hpp', + 'rabbit/ClassMember.hpp', + 'rabbit/Instance.hpp', 'rabbit/AutoDec.hpp', 'rabbit/VirtualMachine.hpp', 'rabbit/sqstate.hpp', diff --git a/rabbit/sqclass.cpp b/rabbit/Class.cpp similarity index 52% rename from rabbit/sqclass.cpp rename to rabbit/Class.cpp index d1f05ea..9d27fa8 100644 --- a/rabbit/sqclass.cpp +++ b/rabbit/Class.cpp @@ -5,17 +5,11 @@ * @copyright 2003-2017, Alberto DEMICHELIS, all right reserved * @license MPL-2 (see license file) */ -#include -#include -#include -#include -#include -#include -#include +#include +#include -SQClass::SQClass(SQSharedState *ss,SQClass *base) -{ +rabbit::Class::Class(SQSharedState *ss,rabbit::Class *base) { _base = base; _typetag = 0; _hook = NULL; @@ -34,7 +28,7 @@ SQClass::SQClass(SQSharedState *ss,SQClass *base) __ObjaddRef(_members); } -void SQClass::finalize() { +void rabbit::Class::finalize() { _attributes.Null(); _NULL_SQOBJECT_VECTOR(_defaultvalues,_defaultvalues.size()); _methods.resize(0); @@ -45,21 +39,21 @@ void SQClass::finalize() { } } -SQClass::~SQClass() -{ +rabbit::Class::~Class() { finalize(); } -bool SQClass::newSlot(SQSharedState *ss,const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val,bool bstatic) -{ +bool rabbit::Class::newSlot(SQSharedState *ss,const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val,bool bstatic) { rabbit::ObjectPtr temp; bool belongs_to_static_table = sq_type(val) == rabbit::OT_CLOSURE || sq_type(val) == rabbit::OT_NATIVECLOSURE || bstatic; - if(_locked && !belongs_to_static_table) - return false; //the class already has an instance so cannot be modified - if(_members->get(key,temp) && _isfield(temp)) //overrides the default value - { + if(_locked && !belongs_to_static_table) { + //the class already has an instance so cannot be modified + return false; + } + //overrides the default value + if(_members->get(key,temp) && _isfield(temp)) { _defaultvalues[_member_idx(temp)].val = val; return true; } @@ -69,8 +63,7 @@ bool SQClass::newSlot(SQSharedState *ss,const rabbit::ObjectPtr &key,const rabbi || sq_type(val) == rabbit::OT_NATIVECLOSURE ) && (mmidx = ss->getMetaMethodIdxByName(key)) != -1) { _metamethods[mmidx] = val; - } - else { + } else { rabbit::ObjectPtr theval = val; if(_base && sq_type(val) == rabbit::OT_CLOSURE) { theval = _closure(val)->clone(); @@ -83,39 +76,37 @@ bool SQClass::newSlot(SQSharedState *ss,const rabbit::ObjectPtr &key,const rabbi if(isconstructor) { _constructoridx = (int64_t)_methods.size(); } - SQClassMember m; + rabbit::ClassMember m; m.val = theval; _members->newSlot(key,rabbit::ObjectPtr(_make_method_idx(_methods.size()))); _methods.pushBack(m); - } - else { + } else { _methods[_member_idx(temp)].val = theval; } } return true; } - SQClassMember m; + rabbit::ClassMember m; m.val = val; _members->newSlot(key,rabbit::ObjectPtr(_make_field_idx(_defaultvalues.size()))); _defaultvalues.pushBack(m); return true; } -SQInstance *SQClass::createInstance() -{ - if(!_locked) lock(); - return SQInstance::create(NULL,this); +rabbit::Instance *rabbit::Class::createInstance() { + if(!_locked) { + lock(); + } + return rabbit::Instance::create(NULL,this); } -int64_t SQClass::next(const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey, rabbit::ObjectPtr &outval) -{ +int64_t rabbit::Class::next(const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey, rabbit::ObjectPtr &outval) { rabbit::ObjectPtr oval; int64_t idx = _members->next(false,refpos,outkey,oval); if(idx != -1) { if(_ismethod(oval)) { outval = _methods[_member_idx(oval)].val; - } - else { + } else { rabbit::ObjectPtr &o = _defaultvalues[_member_idx(oval)].val; outval = _realval(o); } @@ -123,21 +114,20 @@ int64_t SQClass::next(const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey return idx; } -bool SQClass::setAttributes(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val) -{ +bool rabbit::Class::setAttributes(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val) { rabbit::ObjectPtr idx; if(_members->get(key,idx)) { - if(_isfield(idx)) + if(_isfield(idx)) { _defaultvalues[_member_idx(idx)].attrs = val; - else + } else { _methods[_member_idx(idx)].attrs = val; + } return true; } return false; } -bool SQClass::getAttributes(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &outval) -{ +bool rabbit::Class::getAttributes(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &outval) { rabbit::ObjectPtr idx; if(_members->get(key,idx)) { outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs); @@ -146,65 +136,4 @@ bool SQClass::getAttributes(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &outv return false; } -/////////////////////////////////////////////////////////////////////// -void SQInstance::init(SQSharedState *ss) -{ - _userpointer = NULL; - _hook = NULL; - __ObjaddRef(_class); - _delegate = _class->_members; -} -SQInstance::SQInstance(SQSharedState *ss, SQClass *c, int64_t memsize) -{ - _memsize = memsize; - _class = c; - uint64_t nvalues = _class->_defaultvalues.size(); - for(uint64_t n = 0; n < nvalues; n++) { - new (&_values[n]) rabbit::ObjectPtr(_class->_defaultvalues[n].val); - } - init(ss); -} - -SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, int64_t memsize) -{ - _memsize = memsize; - _class = i->_class; - uint64_t nvalues = _class->_defaultvalues.size(); - for(uint64_t n = 0; n < nvalues; n++) { - new (&_values[n]) rabbit::ObjectPtr(i->_values[n]); - } - init(ss); -} - -void SQInstance::finalize() -{ - uint64_t nvalues = _class->_defaultvalues.size(); - __Objrelease(_class); - _NULL_SQOBJECT_VECTOR(_values,nvalues); -} - -SQInstance::~SQInstance() -{ - if(_class){ finalize(); } //if _class is null it was already finalized by the GC -} - -bool SQInstance::getMetaMethod(rabbit::VirtualMachine* SQ_UNUSED_ARG(v),rabbit::MetaMethod mm,rabbit::ObjectPtr &res) -{ - if(sq_type(_class->_metamethods[mm]) != rabbit::OT_NULL) { - res = _class->_metamethods[mm]; - return true; - } - return false; -} - -bool SQInstance::instanceOf(SQClass *trg) -{ - SQClass *parent = _class; - while(parent != NULL) { - if(parent == trg) - return true; - parent = parent->_base; - } - return false; -} diff --git a/rabbit/Class.hpp b/rabbit/Class.hpp new file mode 100644 index 0000000..de1f697 --- /dev/null +++ b/rabbit/Class.hpp @@ -0,0 +1,75 @@ +/** + * @author Alberto DEMICHELIS + * @author Edouard DUPIN + * @copyright 2018, Edouard DUPIN, all right reserved + * @copyright 2003-2017, Alberto DEMICHELIS, all right reserved + * @license MPL-2 (see license file) + */ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rabbit { + class Class : public rabbit::RefCounted { + public: + Class(SQSharedState *ss,rabbit::Class *base); + public: + static Class* create(SQSharedState *ss, Class *base) { + rabbit::Class *newclass = (Class *)SQ_MALLOC(sizeof(Class)); + new (newclass) Class(ss, base); + return newclass; + } + ~Class(); + bool newSlot(SQSharedState *ss, const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val,bool bstatic); + bool get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val) { + if(_members->get(key,val)) { + if(_isfield(val)) { + rabbit::ObjectPtr &o = _defaultvalues[_member_idx(val)].val; + val = _realval(o); + } else { + val = _methods[_member_idx(val)].val; + } + return true; + } + return false; + } + bool getConstructor(rabbit::ObjectPtr &ctor) { + if(_constructoridx != -1) { + ctor = _methods[_constructoridx].val; + return true; + } + return false; + } + bool setAttributes(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val); + bool getAttributes(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &outval); + void lock() { _locked = true; if(_base) _base->lock(); } + void release() { + if (_hook) { _hook(_typetag,0);} + sq_delete(this, Class); + } + void finalize(); + int64_t next(const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey, rabbit::ObjectPtr &outval); + rabbit::Instance *createInstance(); + SQTable *_members; + rabbit::Class *_base; + etk::Vector _defaultvalues; + etk::Vector _methods; + rabbit::ObjectPtr _metamethods[rabbit::MT_LAST]; + rabbit::ObjectPtr _attributes; + rabbit::UserPointer _typetag; + SQRELEASEHOOK _hook; + bool _locked; + int64_t _constructoridx; + int64_t _udsize; + }; + #define calcinstancesize(_theclass_) \ + (_theclass_->_udsize + sq_aligning(sizeof(rabbit::Instance) + (sizeof(rabbit::ObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0)))) +} + diff --git a/rabbit/ClassMember.cpp b/rabbit/ClassMember.cpp new file mode 100644 index 0000000..515b6dc --- /dev/null +++ b/rabbit/ClassMember.cpp @@ -0,0 +1,9 @@ +/** + * @author Alberto DEMICHELIS + * @author Edouard DUPIN + * @copyright 2018, Edouard DUPIN, all right reserved + * @copyright 2003-2017, Alberto DEMICHELIS, all right reserved + * @license MPL-2 (see license file) + */ +#include + diff --git a/rabbit/ClassMember.hpp b/rabbit/ClassMember.hpp new file mode 100644 index 0000000..09bdfa5 --- /dev/null +++ b/rabbit/ClassMember.hpp @@ -0,0 +1,37 @@ +/** + * @author Alberto DEMICHELIS + * @author Edouard DUPIN + * @copyright 2018, Edouard DUPIN, all right reserved + * @copyright 2003-2017, Alberto DEMICHELIS, all right reserved + * @license MPL-2 (see license file) + */ +#pragma once + +#include +#include + +#include + + + +#define MEMBER_TYPE_METHOD 0x01000000 +#define MEMBER_TYPE_FIELD 0x02000000 + +#define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD) +#define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD) +#define _make_method_idx(i) ((int64_t)(MEMBER_TYPE_METHOD|i)) +#define _make_field_idx(i) ((int64_t)(MEMBER_TYPE_FIELD|i)) +#define _member_type(o) (_integer(o)&0xFF000000) +#define _member_idx(o) (_integer(o)&0x00FFFFFF) + +namespace rabbit { + class ClassMember { + public: + rabbit::ObjectPtr val; + rabbit::ObjectPtr attrs; + void Null() { + val.Null(); + attrs.Null(); + } + }; +} diff --git a/rabbit/Instance.cpp b/rabbit/Instance.cpp new file mode 100644 index 0000000..596154f --- /dev/null +++ b/rabbit/Instance.cpp @@ -0,0 +1,66 @@ +/** + * @author Alberto DEMICHELIS + * @author Edouard DUPIN + * @copyright 2018, Edouard DUPIN, all right reserved + * @copyright 2003-2017, Alberto DEMICHELIS, all right reserved + * @license MPL-2 (see license file) + */ +#include + +void rabbit::Instance::init(SQSharedState *ss) { + _userpointer = NULL; + _hook = NULL; + __ObjaddRef(_class); + _delegate = _class->_members; +} + +rabbit::Instance::Instance(SQSharedState *ss, rabbit::Class *c, int64_t memsize) { + _memsize = memsize; + _class = c; + uint64_t nvalues = _class->_defaultvalues.size(); + for(uint64_t n = 0; n < nvalues; n++) { + new (&_values[n]) rabbit::ObjectPtr(_class->_defaultvalues[n].val); + } + init(ss); +} + +rabbit::Instance::Instance(SQSharedState *ss, rabbit::Instance *i, int64_t memsize) { + _memsize = memsize; + _class = i->_class; + uint64_t nvalues = _class->_defaultvalues.size(); + for(uint64_t n = 0; n < nvalues; n++) { + new (&_values[n]) rabbit::ObjectPtr(i->_values[n]); + } + init(ss); +} + +void rabbit::Instance::finalize() { + uint64_t nvalues = _class->_defaultvalues.size(); + __Objrelease(_class); + _NULL_SQOBJECT_VECTOR(_values,nvalues); +} + +rabbit::Instance::~Instance() { + if(_class){ + finalize(); + } +} + +bool rabbit::Instance::getMetaMethod(rabbit::VirtualMachine* SQ_UNUSED_ARG(v),rabbit::MetaMethod mm,rabbit::ObjectPtr &res) { + if(sq_type(_class->_metamethods[mm]) != rabbit::OT_NULL) { + res = _class->_metamethods[mm]; + return true; + } + return false; +} + +bool rabbit::Instance::instanceOf(rabbit::Class *trg) { + rabbit::Class *parent = _class; + while(parent != NULL) { + if(parent == trg) { + return true; + } + parent = parent->_base; + } + return false; +} diff --git a/rabbit/Instance.hpp b/rabbit/Instance.hpp new file mode 100644 index 0000000..78c4bc9 --- /dev/null +++ b/rabbit/Instance.hpp @@ -0,0 +1,87 @@ +/** + * @author Alberto DEMICHELIS + * @author Edouard DUPIN + * @copyright 2018, Edouard DUPIN, all right reserved + * @copyright 2003-2017, Alberto DEMICHELIS, all right reserved + * @license MPL-2 (see license file) + */ +#pragma once + +#include +#include +#include +#include + +#include +#include +#include + +namespace rabbit { + class Instance : public rabbit::Delegable { + public: + void init(SQSharedState *ss); + Instance(SQSharedState *ss, rabbit::Class *c, int64_t memsize); + Instance(SQSharedState *ss, Instance *c, int64_t memsize); + public: + static Instance* create(SQSharedState *ss,rabbit::Class *theclass) { + int64_t size = calcinstancesize(theclass); + Instance *newinst = (Instance *)SQ_MALLOC(size); + new (newinst) Instance(ss, theclass,size); + if(theclass->_udsize) { + newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize); + } + return newinst; + } + Instance *clone(SQSharedState *ss) + { + int64_t size = calcinstancesize(_class); + Instance *newinst = (Instance *)SQ_MALLOC(size); + new (newinst) Instance(ss, this,size); + if(_class->_udsize) { + newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize); + } + return newinst; + } + ~Instance(); + bool get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val) { + if(_class->_members->get(key,val)) { + if(_isfield(val)) { + rabbit::ObjectPtr &o = _values[_member_idx(val)]; + val = _realval(o); + } + else { + val = _class->_methods[_member_idx(val)].val; + } + return true; + } + return false; + } + bool set(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val) { + rabbit::ObjectPtr idx; + if(_class->_members->get(key,idx) && _isfield(idx)) { + _values[_member_idx(idx)] = val; + return true; + } + return false; + } + void release() { + _uiRef++; + if (_hook) { _hook(_userpointer,0);} + _uiRef--; + if(_uiRef > 0) return; + int64_t size = _memsize; + this->~Instance(); + SQ_FREE(this, size); + } + void finalize(); + bool instanceOf(rabbit::Class *trg); + bool getMetaMethod(rabbit::VirtualMachine *v,rabbit::MetaMethod mm,rabbit::ObjectPtr &res); + + rabbit::Class *_class; + rabbit::UserPointer _userpointer; + SQRELEASEHOOK _hook; + int64_t _memsize; + rabbit::ObjectPtr _values[1]; + }; +} + diff --git a/rabbit/ObjectPtr.cpp b/rabbit/ObjectPtr.cpp index f81094e..6779ca5 100644 --- a/rabbit/ObjectPtr.cpp +++ b/rabbit/ObjectPtr.cpp @@ -50,8 +50,8 @@ RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_TABLE, SQTable, pTable) -RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_CLASS, SQClass, pClass) -RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_INSTANCE, SQInstance, pInstance) +RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_CLASS, rabbit::Class, pClass) +RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_INSTANCE, rabbit::Instance, pInstance) RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_ARRAY, rabbit::Array, pArray) RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_CLOSURE, SQClosure, pClosure) RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_NATIVECLOSURE, SQNativeClosure, pNativeClosure) diff --git a/rabbit/ObjectPtr.hpp b/rabbit/ObjectPtr.hpp index cbdf488..05a6085 100644 --- a/rabbit/ObjectPtr.hpp +++ b/rabbit/ObjectPtr.hpp @@ -34,8 +34,8 @@ namespace rabbit { ObjectPtr(const Object& _obj); RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_TABLE, SQTable, pTable) - RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_CLASS, SQClass, pClass) - RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_INSTANCE, SQInstance, pInstance) + RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_CLASS, rabbit::Class, pClass) + RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_INSTANCE, rabbit::Instance, pInstance) RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_ARRAY, rabbit::Array, pArray) RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_CLOSURE, SQClosure, pClosure) RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_NATIVECLOSURE, SQNativeClosure, pNativeClosure) diff --git a/rabbit/ObjectValue.hpp b/rabbit/ObjectValue.hpp index 81aaab1..e0f4b69 100644 --- a/rabbit/ObjectValue.hpp +++ b/rabbit/ObjectValue.hpp @@ -23,9 +23,9 @@ namespace rabbit { int64_t nInteger; float_t fFloat; struct SQFunctionProto *pFunctionProto; - struct SQClass *pClass; - struct SQInstance *pInstance; + rabbit::Class *pClass; + rabbit::Instance *pInstance; rabbit::Delegable *pDelegable; rabbit::UserPointer pUserPointer; rabbit::WeakRef* pWeakRef; diff --git a/rabbit/VirtualMachine.cpp b/rabbit/VirtualMachine.cpp index 2ea9adc..1866fd4 100644 --- a/rabbit/VirtualMachine.cpp +++ b/rabbit/VirtualMachine.cpp @@ -16,7 +16,8 @@ #include #include #include -#include +#include + #define TOP() (_stack[_top-1]) #define TARGET _stack[_stackbase+arg0] @@ -616,7 +617,7 @@ bool rabbit::VirtualMachine::CLOSURE_OP(rabbit::ObjectPtr &target, SQFunctionPro bool rabbit::VirtualMachine::CLASS_OP(rabbit::ObjectPtr &target,int64_t baseclass,int64_t attributes) { - SQClass *base = NULL; + rabbit::Class *base = NULL; rabbit::ObjectPtr attrs; if(baseclass != -1) { if(sq_type(_stack[_stackbase+baseclass]) != rabbit::OT_CLASS) { raise_error(_SC("trying to inherit from a %s"),getTypeName(_stack[_stackbase+baseclass])); return false; } @@ -625,7 +626,7 @@ bool rabbit::VirtualMachine::CLASS_OP(rabbit::ObjectPtr &target,int64_t baseclas if(attributes != MAX_FUNC_STACKSIZE) { attrs = _stack[_stackbase+attributes]; } - target = SQClass::create(_get_shared_state(this),base); + target = rabbit::Class::create(_get_shared_state(this),base); if(sq_type(_class(target)->_metamethods[MT_INHERITED]) != rabbit::OT_NULL) { int nparams = 2; rabbit::ObjectPtr ret; @@ -1103,7 +1104,7 @@ exception_trap: assert(0); } -bool rabbit::VirtualMachine::createClassInstance(SQClass *theclass, rabbit::ObjectPtr &inst, rabbit::ObjectPtr &constructor) +bool rabbit::VirtualMachine::createClassInstance(rabbit::Class *theclass, rabbit::ObjectPtr &inst, rabbit::ObjectPtr &constructor) { inst = theclass->createInstance(); if(!theclass->getConstructor(constructor)) { @@ -1455,7 +1456,7 @@ bool rabbit::VirtualMachine::newSlotA(const rabbit::ObjectPtr &self,const rabbit raise_error(_SC("object must be a class")); return false; } - SQClass *c = _class(self); + rabbit::Class *c = _class(self); if(!raw) { rabbit::ObjectPtr &mm = c->_metamethods[MT_NEWMEMBER]; if(sq_type(mm) != rabbit::OT_NULL ) { diff --git a/rabbit/VirtualMachine.hpp b/rabbit/VirtualMachine.hpp index 9fb6d7a..3e43dcf 100644 --- a/rabbit/VirtualMachine.hpp +++ b/rabbit/VirtualMachine.hpp @@ -67,7 +67,7 @@ namespace rabbit { bool tailcall(SQClosure *closure, int64_t firstparam, int64_t nparams); //starts a RABBIT call in the same "Execution loop" bool startcall(SQClosure *closure, int64_t target, int64_t nargs, int64_t stackbase, bool tailcall); - bool createClassInstance(SQClass *theclass, rabbit::ObjectPtr &inst, rabbit::ObjectPtr &constructor); + bool createClassInstance(rabbit::Class *theclass, rabbit::ObjectPtr &inst, rabbit::ObjectPtr &constructor); //call a generic closure pure RABBIT or NATIVE bool call(rabbit::ObjectPtr &closure, int64_t nparams, int64_t stackbase, rabbit::ObjectPtr &outres,rabbit::Bool raiseerror); rabbit::Result Suspend(); diff --git a/rabbit/sqapi.cpp b/rabbit/sqapi.cpp index 917c7c5..8b1362b 100644 --- a/rabbit/sqapi.cpp +++ b/rabbit/sqapi.cpp @@ -15,7 +15,8 @@ #include #include #include -#include +#include + #include static bool sq_aux_gettypedarg(rabbit::VirtualMachine* v,int64_t idx,rabbit::ObjectType type,rabbit::ObjectPtr **o) @@ -283,14 +284,14 @@ void sq_newarray(rabbit::VirtualMachine* v,int64_t size) rabbit::Result sq_newclass(rabbit::VirtualMachine* v,rabbit::Bool hasbase) { - SQClass *baseclass = NULL; + rabbit::Class *baseclass = NULL; if(hasbase) { rabbit::ObjectPtr &base = stack_get(v,-1); if(sq_type(base) != rabbit::OT_CLASS) return sq_throwerror(v,_SC("invalid base type")); baseclass = _class(base); } - SQClass *newclass = SQClass::create(_get_shared_state(v), baseclass); + rabbit::Class *newclass = rabbit::Class::create(_get_shared_state(v), baseclass); if(baseclass) v->pop(); v->push(newclass); return SQ_OK; @@ -820,7 +821,7 @@ rabbit::Result sq_getinstanceup(rabbit::VirtualMachine* v, int64_t idx, rabbit:: if(sq_type(o) != rabbit::OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance")); (*p) = _instance(o)->_userpointer; if(typetag != 0) { - SQClass *cl = _instance(o)->_class; + rabbit::Class *cl = _instance(o)->_class; do{ if(cl->_typetag == typetag) return SQ_OK; @@ -1460,9 +1461,9 @@ rabbit::Result _getmemberbyhandle(rabbit::VirtualMachine* v,rabbit::ObjectPtr &s { switch(sq_type(self)) { case rabbit::OT_INSTANCE: { - SQInstance *i = _instance(self); + rabbit::Instance *i = _instance(self); if(handle->_static) { - SQClass *c = i->_class; + rabbit::Class *c = i->_class; val = &c->_methods[handle->_index].val; } else { @@ -1472,7 +1473,7 @@ rabbit::Result _getmemberbyhandle(rabbit::VirtualMachine* v,rabbit::ObjectPtr &s } break; case rabbit::OT_CLASS: { - SQClass *c = _class(self); + rabbit::Class *c = _class(self); if(handle->_static) { val = &c->_methods[handle->_index].val; } diff --git a/rabbit/sqbaselib.cpp b/rabbit/sqbaselib.cpp index 0e85904..666cee2 100644 --- a/rabbit/sqbaselib.cpp +++ b/rabbit/sqbaselib.cpp @@ -12,7 +12,7 @@ #include #include #include -#include + #include #include #include diff --git a/rabbit/sqclass.hpp b/rabbit/sqclass.hpp deleted file mode 100644 index befe9c9..0000000 --- a/rabbit/sqclass.hpp +++ /dev/null @@ -1,158 +0,0 @@ -/** - * @author Alberto DEMICHELIS - * @author Edouard DUPIN - * @copyright 2018, Edouard DUPIN, all right reserved - * @copyright 2003-2017, Alberto DEMICHELIS, all right reserved - * @license MPL-2 (see license file) - */ -#pragma once - -struct SQInstance; - -struct SQClassMember { - rabbit::ObjectPtr val; - rabbit::ObjectPtr attrs; - void Null() { - val.Null(); - attrs.Null(); - } -}; - -typedef etk::Vector SQClassMemberVec; - -#define MEMBER_TYPE_METHOD 0x01000000 -#define MEMBER_TYPE_FIELD 0x02000000 - -#define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD) -#define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD) -#define _make_method_idx(i) ((int64_t)(MEMBER_TYPE_METHOD|i)) -#define _make_field_idx(i) ((int64_t)(MEMBER_TYPE_FIELD|i)) -#define _member_type(o) (_integer(o)&0xFF000000) -#define _member_idx(o) (_integer(o)&0x00FFFFFF) - -struct SQClass : public rabbit::RefCounted -{ - SQClass(SQSharedState *ss,SQClass *base); -public: - static SQClass* create(SQSharedState *ss,SQClass *base) { - SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass)); - new (newclass) SQClass(ss, base); - return newclass; - } - ~SQClass(); - bool newSlot(SQSharedState *ss, const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val,bool bstatic); - bool get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val) { - if(_members->get(key,val)) { - if(_isfield(val)) { - rabbit::ObjectPtr &o = _defaultvalues[_member_idx(val)].val; - val = _realval(o); - } - else { - val = _methods[_member_idx(val)].val; - } - return true; - } - return false; - } - bool getConstructor(rabbit::ObjectPtr &ctor) - { - if(_constructoridx != -1) { - ctor = _methods[_constructoridx].val; - return true; - } - return false; - } - bool setAttributes(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val); - bool getAttributes(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &outval); - void lock() { _locked = true; if(_base) _base->lock(); } - void release() { - if (_hook) { _hook(_typetag,0);} - sq_delete(this, SQClass); - } - void finalize(); - int64_t next(const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey, rabbit::ObjectPtr &outval); - SQInstance *createInstance(); - SQTable *_members; - SQClass *_base; - SQClassMemberVec _defaultvalues; - SQClassMemberVec _methods; - rabbit::ObjectPtr _metamethods[rabbit::MT_LAST]; - rabbit::ObjectPtr _attributes; - rabbit::UserPointer _typetag; - SQRELEASEHOOK _hook; - bool _locked; - int64_t _constructoridx; - int64_t _udsize; -}; - -#define calcinstancesize(_theclass_) \ - (_theclass_->_udsize + sq_aligning(sizeof(SQInstance) + (sizeof(rabbit::ObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0)))) - -struct SQInstance : public rabbit::Delegable -{ - void init(SQSharedState *ss); - SQInstance(SQSharedState *ss, SQClass *c, int64_t memsize); - SQInstance(SQSharedState *ss, SQInstance *c, int64_t memsize); -public: - static SQInstance* create(SQSharedState *ss,SQClass *theclass) { - - int64_t size = calcinstancesize(theclass); - SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); - new (newinst) SQInstance(ss, theclass,size); - if(theclass->_udsize) { - newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize); - } - return newinst; - } - SQInstance *clone(SQSharedState *ss) - { - int64_t size = calcinstancesize(_class); - SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); - new (newinst) SQInstance(ss, this,size); - if(_class->_udsize) { - newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize); - } - return newinst; - } - ~SQInstance(); - bool get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val) { - if(_class->_members->get(key,val)) { - if(_isfield(val)) { - rabbit::ObjectPtr &o = _values[_member_idx(val)]; - val = _realval(o); - } - else { - val = _class->_methods[_member_idx(val)].val; - } - return true; - } - return false; - } - bool set(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val) { - rabbit::ObjectPtr idx; - if(_class->_members->get(key,idx) && _isfield(idx)) { - _values[_member_idx(idx)] = val; - return true; - } - return false; - } - void release() { - _uiRef++; - if (_hook) { _hook(_userpointer,0);} - _uiRef--; - if(_uiRef > 0) return; - int64_t size = _memsize; - this->~SQInstance(); - SQ_FREE(this, size); - } - void finalize(); - bool instanceOf(SQClass *trg); - bool getMetaMethod(rabbit::VirtualMachine *v,rabbit::MetaMethod mm,rabbit::ObjectPtr &res); - - SQClass *_class; - rabbit::UserPointer _userpointer; - SQRELEASEHOOK _hook; - int64_t _memsize; - rabbit::ObjectPtr _values[1]; -}; - diff --git a/rabbit/sqclosure.hpp b/rabbit/sqclosure.hpp index 81662bc..a317067 100644 --- a/rabbit/sqclosure.hpp +++ b/rabbit/sqclosure.hpp @@ -7,10 +7,12 @@ */ #pragma once +#include +#include + #define _CALC_CLOSURE_SIZE(func) (sizeof(SQClosure) + (func->_noutervalues*sizeof(rabbit::ObjectPtr)) + (func->_ndefaultparams*sizeof(rabbit::ObjectPtr))) struct SQFunctionProto; -struct SQClass; struct SQClosure : public rabbit::RefCounted { private: @@ -64,7 +66,7 @@ public: static bool load(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQREADFUNC read,rabbit::ObjectPtr &ret); rabbit::WeakRef *_env; rabbit::WeakRef *_root; - SQClass *_base; + rabbit::Class *_base; SQFunctionProto *_function; rabbit::ObjectPtr *_outervalues; rabbit::ObjectPtr *_defaultparams; diff --git a/rabbit/sqconfig.hpp b/rabbit/sqconfig.hpp index 82beddb..2e0d572 100644 --- a/rabbit/sqconfig.hpp +++ b/rabbit/sqconfig.hpp @@ -131,8 +131,6 @@ struct SQClosure; struct SQGenerator; struct SQNativeClosure; struct SQFunctionProto; -struct SQClass; -struct SQInstance; struct SQOuter; struct SQSharedState; namespace rabbit { @@ -145,4 +143,6 @@ namespace rabbit { class FunctionInfo; class StackInfos; class MemberHandle; + class Instance; + class Class; } \ No newline at end of file diff --git a/rabbit/sqobject.cpp b/rabbit/sqobject.cpp index 7f57417..2717dd1 100644 --- a/rabbit/sqobject.cpp +++ b/rabbit/sqobject.cpp @@ -12,7 +12,7 @@ #include #include #include -#include + #include SQString *SQString::create(SQSharedState *ss,const rabbit::Char *s,int64_t len) diff --git a/rabbit/sqstate.cpp b/rabbit/sqstate.cpp index c915a77..f93456b 100644 --- a/rabbit/sqstate.cpp +++ b/rabbit/sqstate.cpp @@ -14,7 +14,7 @@ #include #include #include -#include + SQSharedState::SQSharedState() {