From 45e2df01f0da5be993605a077858a2b9d0825a24 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Thu, 28 Jun 2018 22:29:10 +0200 Subject: [PATCH] [DEV] continue rework (little bug...) --- lutin_rabbit-core.py | 17 +- rabbit/Array.hpp | 4 +- rabbit/Class.cpp | 49 +++- rabbit/Class.hpp | 46 +-- rabbit/Delegable.cpp | 10 +- rabbit/Delegable.hpp | 6 +- rabbit/Hash.cpp | 13 + rabbit/Hash.hpp | 17 ++ rabbit/Instance.cpp | 65 ++++- rabbit/Instance.hpp | 63 +--- rabbit/Object.hpp | 9 + rabbit/ObjectPtr.cpp | 4 +- rabbit/ObjectPtr.hpp | 4 +- rabbit/ObjectValue.hpp | 13 +- rabbit/RefTable.cpp | 160 ++++++++++ rabbit/RefTable.hpp | 42 +++ rabbit/SharedState.cpp | 221 ++++++++++++++ rabbit/SharedState.hpp | 85 ++++++ rabbit/String.cpp | 45 +++ rabbit/String.hpp | 32 ++ rabbit/StringTable.cpp | 102 +++++++ rabbit/StringTable.hpp | 33 +++ rabbit/{sqtable.cpp => Table.cpp} | 107 +++++-- rabbit/Table.hpp | 55 ++++ rabbit/UserData.hpp | 4 +- rabbit/VirtualMachine.cpp | 18 +- rabbit/VirtualMachine.hpp | 7 +- rabbit/rabbit.hpp | 13 +- rabbit/sqapi.cpp | 30 +- rabbit/sqbaselib.cpp | 66 ++--- rabbit/sqclosure.hpp | 16 +- rabbit/sqcompiler.cpp | 14 +- rabbit/sqconfig.hpp | 13 +- rabbit/sqdebug.cpp | 18 +- rabbit/sqfuncproto.hpp | 4 +- rabbit/sqfuncstate.cpp | 16 +- rabbit/sqfuncstate.hpp | 8 +- rabbit/sqlexer.cpp | 10 +- rabbit/sqlexer.hpp | 6 +- rabbit/sqobject.cpp | 33 +-- rabbit/sqobject.hpp | 13 - rabbit/sqpcheader.hpp | 2 +- rabbit/sqstate.cpp | 468 ------------------------------ rabbit/sqstate.hpp | 131 --------- rabbit/sqstring.hpp | 35 --- rabbit/sqtable.hpp | 120 -------- 46 files changed, 1187 insertions(+), 1060 deletions(-) create mode 100644 rabbit/Hash.cpp create mode 100644 rabbit/Hash.hpp create mode 100644 rabbit/RefTable.cpp create mode 100644 rabbit/RefTable.hpp create mode 100644 rabbit/SharedState.cpp create mode 100644 rabbit/SharedState.hpp create mode 100644 rabbit/String.cpp create mode 100644 rabbit/String.hpp create mode 100644 rabbit/StringTable.cpp create mode 100644 rabbit/StringTable.hpp rename rabbit/{sqtable.cpp => Table.cpp} (63%) create mode 100644 rabbit/Table.hpp delete mode 100644 rabbit/sqstate.cpp delete mode 100644 rabbit/sqstate.hpp delete mode 100644 rabbit/sqstring.hpp delete mode 100644 rabbit/sqtable.hpp diff --git a/lutin_rabbit-core.py b/lutin_rabbit-core.py index 84db1d6..b243d3a 100644 --- a/lutin_rabbit-core.py +++ b/lutin_rabbit-core.py @@ -27,6 +27,12 @@ def get_version(): def configure(target, my_module): my_module.add_src_file([ + 'rabbit/Hash.cpp', + 'rabbit/RefTable.cpp', + 'rabbit/SharedState.cpp', + 'rabbit/String.cpp', + 'rabbit/StringTable.cpp', + 'rabbit/Table.cpp', 'rabbit/sqmem.cpp', 'rabbit/sqbaselib.cpp', 'rabbit/sqapi.cpp', @@ -36,8 +42,6 @@ def configure(target, my_module): 'rabbit/Instance.cpp', 'rabbit/AutoDec.cpp', 'rabbit/VirtualMachine.cpp', - 'rabbit/sqtable.cpp', - 'rabbit/sqstate.cpp', 'rabbit/sqobject.cpp', 'rabbit/sqcompiler.cpp', 'rabbit/sqdebug.cpp', @@ -64,12 +68,17 @@ def configure(target, my_module): 'etk-base', ]) my_module.add_header_file([ + 'rabbit/Hash.hpp', + 'rabbit/RefTable.hpp', + 'rabbit/SharedState.hpp', + 'rabbit/String.hpp', + 'rabbit/StringTable.hpp', + 'rabbit/Table.hpp', 'rabbit/Class.hpp', 'rabbit/ClassMember.hpp', 'rabbit/Instance.hpp', 'rabbit/AutoDec.hpp', 'rabbit/VirtualMachine.hpp', - 'rabbit/sqstate.hpp', 'rabbit/rabbit.hpp', 'rabbit/sqobject.hpp', 'rabbit/sqopcodes.hpp', @@ -83,8 +92,6 @@ def configure(target, my_module): 'rabbit/sqclosure.hpp', 'rabbit/sqlexer.hpp', 'rabbit/sqfuncstate.hpp', - 'rabbit/sqstring.hpp', - 'rabbit/sqtable.hpp', 'rabbit/RefCounted.hpp', 'rabbit/WeakRef.hpp', 'rabbit/Delegable.hpp', diff --git a/rabbit/Array.hpp b/rabbit/Array.hpp index 4192581..2219f6d 100644 --- a/rabbit/Array.hpp +++ b/rabbit/Array.hpp @@ -11,7 +11,7 @@ namespace rabbit { class Array : public rabbit::RefCounted { private: - Array(SQSharedState* _ss, + Array(rabbit::SharedState* _ss, int64_t _nsize) { m_data.resize(_nsize); } @@ -20,7 +20,7 @@ namespace rabbit { } public: // TODO : remove this ETK_ALLOC can do it natively ... - static Array* create(SQSharedState* _ss, + static Array* create(rabbit::SharedState* _ss, int64_t _ninitialsize) { Array *newarray=(Array*)SQ_MALLOC(sizeof(Array)); new (newarray) Array(_ss, _ninitialsize); diff --git a/rabbit/Class.cpp b/rabbit/Class.cpp index 9d27fa8..078a997 100644 --- a/rabbit/Class.cpp +++ b/rabbit/Class.cpp @@ -7,9 +7,11 @@ */ #include #include +#include +#include -rabbit::Class::Class(SQSharedState *ss,rabbit::Class *base) { +rabbit::Class::Class(rabbit::SharedState *ss, rabbit::Class *base) { _base = base; _typetag = 0; _hook = NULL; @@ -24,7 +26,7 @@ rabbit::Class::Class(SQSharedState *ss,rabbit::Class *base) { _COPY_VECTOR(_metamethods,base->_metamethods, rabbit::MT_LAST); __ObjaddRef(_base); } - _members = base?base->_members->clone() : SQTable::create(ss,0); + _members = base?base->_members->clone() : rabbit::Table::create(ss,0); __ObjaddRef(_members); } @@ -43,7 +45,48 @@ rabbit::Class::~Class() { finalize(); } -bool rabbit::Class::newSlot(SQSharedState *ss,const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val,bool bstatic) { +rabbit::Class* rabbit::Class::create(rabbit::SharedState *ss, Class *base) { + rabbit::Class *newclass = (Class *)SQ_MALLOC(sizeof(Class)); + new (newclass) Class(ss, base); + return newclass; +} + +bool rabbit::Class::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 rabbit::Class::getConstructor(rabbit::ObjectPtr &ctor) { + if(_constructoridx != -1) { + ctor = _methods[_constructoridx].val; + return true; + } + return false; +} + +void rabbit::Class::lock() { + _locked = true; + if(_base) { + _base->lock(); + } +} + +void rabbit::Class::release() { + if (_hook) { + _hook(_typetag,0); + } + sq_delete(this, Class); +} + +bool rabbit::Class::newSlot(rabbit::SharedState *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 diff --git a/rabbit/Class.hpp b/rabbit/Class.hpp index de1f697..31f4572 100644 --- a/rabbit/Class.hpp +++ b/rabbit/Class.hpp @@ -10,54 +10,29 @@ #include #include #include -#include + #include #include -#include #include namespace rabbit { class Class : public rabbit::RefCounted { public: - Class(SQSharedState *ss,rabbit::Class *base); + Class(rabbit::SharedState *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; - } + static Class* create(rabbit::SharedState *ss, Class *base); ~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 newSlot(rabbit::SharedState *ss, const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val,bool bstatic); + bool get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val); + bool getConstructor(rabbit::ObjectPtr &ctor); 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 lock(); + void release(); void finalize(); int64_t next(const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey, rabbit::ObjectPtr &outval); rabbit::Instance *createInstance(); - SQTable *_members; + rabbit::Table *_members; rabbit::Class *_base; etk::Vector _defaultvalues; etk::Vector _methods; @@ -71,5 +46,6 @@ namespace rabbit { }; #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/Delegable.cpp b/rabbit/Delegable.cpp index 9aada09..83726d7 100644 --- a/rabbit/Delegable.cpp +++ b/rabbit/Delegable.cpp @@ -7,9 +7,11 @@ */ #include -#include + #include -#include +#include +#include + bool rabbit::Delegable::getMetaMethod(rabbit::VirtualMachine *v,rabbit::MetaMethod mm,rabbit::ObjectPtr &res) { if(_delegate) { @@ -18,8 +20,8 @@ bool rabbit::Delegable::getMetaMethod(rabbit::VirtualMachine *v,rabbit::MetaMeth return false; } -bool rabbit::Delegable::setDelegate(SQTable *mt) { - SQTable *temp = mt; +bool rabbit::Delegable::setDelegate(rabbit::Table *mt) { + rabbit::Table *temp = mt; if(temp == this) { return false; } diff --git a/rabbit/Delegable.hpp b/rabbit/Delegable.hpp index f8bd789..f2a05a0 100644 --- a/rabbit/Delegable.hpp +++ b/rabbit/Delegable.hpp @@ -12,14 +12,14 @@ #include #include -struct SQTable; namespace rabbit { + class Table; class VirtualMachine; class Delegable : public rabbit::RefCounted { public: - bool setDelegate(SQTable *m); + bool setDelegate(rabbit::Table *m); public: virtual bool getMetaMethod(rabbit::VirtualMachine *v, rabbit::MetaMethod mm, rabbit::ObjectPtr& res); - SQTable *_delegate; + rabbit::Table *_delegate; }; } diff --git a/rabbit/Hash.cpp b/rabbit/Hash.cpp new file mode 100644 index 0000000..bad450d --- /dev/null +++ b/rabbit/Hash.cpp @@ -0,0 +1,13 @@ +/** + * @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 + + + diff --git a/rabbit/Hash.hpp b/rabbit/Hash.hpp new file mode 100644 index 0000000..a91fd2a --- /dev/null +++ b/rabbit/Hash.hpp @@ -0,0 +1,17 @@ +/** + * @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 + +namespace rabbit { + // should be the same size of a pointer + using Hash = size_t; + +} + diff --git a/rabbit/Instance.cpp b/rabbit/Instance.cpp index 596154f..6e64522 100644 --- a/rabbit/Instance.cpp +++ b/rabbit/Instance.cpp @@ -6,15 +6,17 @@ * @license MPL-2 (see license file) */ #include +#include +#include -void rabbit::Instance::init(SQSharedState *ss) { +void rabbit::Instance::init(rabbit::SharedState *ss) { _userpointer = NULL; _hook = NULL; __ObjaddRef(_class); _delegate = _class->_members; } -rabbit::Instance::Instance(SQSharedState *ss, rabbit::Class *c, int64_t memsize) { +rabbit::Instance::Instance(rabbit::SharedState *ss, rabbit::Class *c, int64_t memsize) { _memsize = memsize; _class = c; uint64_t nvalues = _class->_defaultvalues.size(); @@ -24,7 +26,7 @@ rabbit::Instance::Instance(SQSharedState *ss, rabbit::Class *c, int64_t memsize) init(ss); } -rabbit::Instance::Instance(SQSharedState *ss, rabbit::Instance *i, int64_t memsize) { +rabbit::Instance::Instance(rabbit::SharedState *ss, rabbit::Instance *i, int64_t memsize) { _memsize = memsize; _class = i->_class; uint64_t nvalues = _class->_defaultvalues.size(); @@ -64,3 +66,60 @@ bool rabbit::Instance::instanceOf(rabbit::Class *trg) { } return false; } + +rabbit::Instance* rabbit::Instance::create(rabbit::SharedState *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; +} + +rabbit::Instance* rabbit::Instance::clone(rabbit::SharedState *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; +} + +bool rabbit::Instance::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 rabbit::Instance::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 rabbit::Instance::release() { + _uiRef++; + if (_hook) { + _hook(_userpointer,0); + } + _uiRef--; + if(_uiRef > 0) { + return; + } + int64_t size = _memsize; + this->~Instance(); + SQ_FREE(this, size); +} + diff --git a/rabbit/Instance.hpp b/rabbit/Instance.hpp index 78c4bc9..70ef93f 100644 --- a/rabbit/Instance.hpp +++ b/rabbit/Instance.hpp @@ -10,69 +10,26 @@ #include #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); + void init(rabbit::SharedState *ss); + Instance(rabbit::SharedState *ss, rabbit::Class *c, int64_t memsize); + Instance(rabbit::SharedState *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; - } + static Instance* create(rabbit::SharedState *ss,rabbit::Class *theclass); + Instance *clone(rabbit::SharedState *ss); ~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); - } + bool get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val); + bool set(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val); + void release(); void finalize(); bool instanceOf(rabbit::Class *trg); bool getMetaMethod(rabbit::VirtualMachine *v,rabbit::MetaMethod mm,rabbit::ObjectPtr &res); diff --git a/rabbit/Object.hpp b/rabbit/Object.hpp index fe038f7..0eaa178 100644 --- a/rabbit/Object.hpp +++ b/rabbit/Object.hpp @@ -81,4 +81,13 @@ namespace rabbit { #define sq_isweakref(o) ((o)._type==rabbit::OT_WEAKREF) #define sq_type(o) ((o)._type) + inline void _Swap(rabbit::Object &a,rabbit::Object &b) + { + rabbit::ObjectType tOldType = a._type; + rabbit::ObjectValue unOldVal = a._unVal; + a._type = b._type; + a._unVal = b._unVal; + b._type = tOldType; + b._unVal = unOldVal; + } } diff --git a/rabbit/ObjectPtr.cpp b/rabbit/ObjectPtr.cpp index 6779ca5..9f03390 100644 --- a/rabbit/ObjectPtr.cpp +++ b/rabbit/ObjectPtr.cpp @@ -49,7 +49,7 @@ } -RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_TABLE, SQTable, pTable) +RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_TABLE, rabbit::Table, pTable) 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) @@ -57,7 +57,7 @@ RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_CLOSURE, SQClosure, pClosure) RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_NATIVECLOSURE, SQNativeClosure, pNativeClosure) RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_OUTER, SQOuter, pOuter) RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_GENERATOR, SQGenerator, pGenerator) -RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_STRING, SQString, pString) +RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_STRING, rabbit::String, pString) RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_USERDATA, rabbit::UserData, pUserData) RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_WEAKREF, rabbit::WeakRef, pWeakRef) RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_THREAD, rabbit::VirtualMachine, pThread) diff --git a/rabbit/ObjectPtr.hpp b/rabbit/ObjectPtr.hpp index 05a6085..2feac38 100644 --- a/rabbit/ObjectPtr.hpp +++ b/rabbit/ObjectPtr.hpp @@ -33,7 +33,7 @@ namespace rabbit { ObjectPtr(const ObjectPtr& _obj); ObjectPtr(const Object& _obj); - RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_TABLE, SQTable, pTable) + RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_TABLE, rabbit::Table, pTable) 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) @@ -41,7 +41,7 @@ namespace rabbit { RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_NATIVECLOSURE, SQNativeClosure, pNativeClosure) RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_OUTER, SQOuter, pOuter) RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_GENERATOR, SQGenerator, pGenerator) - RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_STRING, SQString, pString) + RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_STRING, rabbit::String, pString) RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_USERDATA, UserData, pUserData) RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_WEAKREF, WeakRef, pWeakRef) RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_THREAD, VirtualMachine, pThread) diff --git a/rabbit/ObjectValue.hpp b/rabbit/ObjectValue.hpp index e0f4b69..1a98eb2 100644 --- a/rabbit/ObjectValue.hpp +++ b/rabbit/ObjectValue.hpp @@ -12,21 +12,20 @@ namespace rabbit { - union ObjectValue - { - struct SQTable *pTable; + union ObjectValue { struct SQClosure *pClosure; struct SQOuter *pOuter; struct SQGenerator *pGenerator; struct SQNativeClosure *pNativeClosure; - struct SQString *pString; int64_t nInteger; float_t fFloat; struct SQFunctionProto *pFunctionProto; - rabbit::Class *pClass; - rabbit::Instance *pInstance; - rabbit::Delegable *pDelegable; + rabbit::Table* pTable; + rabbit::String* pString; + rabbit::Class* pClass; + rabbit::Instance* pInstance; + rabbit::Delegable* pDelegable; rabbit::UserPointer pUserPointer; rabbit::WeakRef* pWeakRef; rabbit::VirtualMachine* pThread; diff --git a/rabbit/RefTable.cpp b/rabbit/RefTable.cpp new file mode 100644 index 0000000..4ae6d8f --- /dev/null +++ b/rabbit/RefTable.cpp @@ -0,0 +1,160 @@ +/** + * @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 +#include + +#include + +rabbit::RefTable::RefTable() +{ + allocNodes(4); +} + +void rabbit::RefTable::finalize() +{ + RefNode *nodes = _nodes; + for(uint64_t n = 0; n < _numofslots; n++) { + nodes->obj.Null(); + nodes++; + } +} + +rabbit::RefTable::~RefTable() +{ + SQ_FREE(_buckets,(_numofslots * sizeof(RefNode *)) + (_numofslots * sizeof(RefNode))); +} + + +void rabbit::RefTable::addRef(rabbit::Object &obj) +{ + rabbit::Hash mainpos; + RefNode *prev; + RefNode *ref = get(obj,mainpos,&prev,true); + ref->refs++; +} + +uint64_t rabbit::RefTable::getRefCount(rabbit::Object &obj) +{ + rabbit::Hash mainpos; + RefNode *prev; + RefNode *ref = get(obj,mainpos,&prev,true); + return ref->refs; +} + + +rabbit::Bool rabbit::RefTable::release(rabbit::Object &obj) +{ + rabbit::Hash mainpos; + RefNode *prev; + RefNode *ref = get(obj,mainpos,&prev,false); + if(ref) { + if(--ref->refs == 0) { + rabbit::ObjectPtr o = ref->obj; + if(prev) { + prev->next = ref->next; + } + else { + _buckets[mainpos] = ref->next; + } + ref->next = _freelist; + _freelist = ref; + _slotused--; + ref->obj.Null(); + //<>test for shrink? + return SQTrue; + } + } + else { + assert(0); + } + return SQFalse; +} + +void rabbit::RefTable::resize(uint64_t size) +{ + RefNode **oldbucks = _buckets; + RefNode *t = _nodes; + uint64_t oldnumofslots = _numofslots; + allocNodes(size); + //rehash + uint64_t nfound = 0; + for(uint64_t n = 0; n < oldnumofslots; n++) { + if(sq_type(t->obj) != rabbit::OT_NULL) { + //add back; + assert(t->refs != 0); + RefNode *nn = add(rabbit::HashObj(t->obj)&(_numofslots-1),t->obj); + nn->refs = t->refs; + t->obj.Null(); + nfound++; + } + t++; + } + assert(nfound == oldnumofslots); + SQ_FREE(oldbucks,(oldnumofslots * sizeof(RefNode *)) + (oldnumofslots * sizeof(RefNode))); +} + +rabbit::RefTable::RefNode* rabbit::RefTable::add(rabbit::Hash mainpos, rabbit::Object &obj) +{ + RefNode *t = _buckets[mainpos]; + RefNode *newnode = _freelist; + newnode->obj = obj; + _buckets[mainpos] = newnode; + _freelist = _freelist->next; + newnode->next = t; + assert(newnode->refs == 0); + _slotused++; + return newnode; +} + +rabbit::RefTable::RefNode* rabbit::RefTable::get(rabbit::Object &obj,rabbit::Hash &mainpos,RefNode **prev,bool addIfNeeded) +{ + RefNode *ref; + mainpos = rabbit::HashObj(obj)&(_numofslots-1); + *prev = NULL; + for (ref = _buckets[mainpos]; ref; ) { + if(_rawval(ref->obj) == _rawval(obj) && sq_type(ref->obj) == sq_type(obj)) + break; + *prev = ref; + ref = ref->next; + } + if(ref == NULL && addIfNeeded) { + if(_numofslots == _slotused) { + assert(_freelist == 0); + resize(_numofslots*2); + mainpos = rabbit::HashObj(obj)&(_numofslots-1); + } + ref = add(mainpos,obj); + } + return ref; +} + +void rabbit::RefTable::allocNodes(uint64_t size) +{ + RefNode **bucks; + RefNode *nodes; + bucks = (RefNode **)SQ_MALLOC((size * sizeof(RefNode *)) + (size * sizeof(RefNode))); + nodes = (RefNode *)&bucks[size]; + RefNode *temp = nodes; + uint64_t n; + for(n = 0; n < size - 1; n++) { + bucks[n] = NULL; + temp->refs = 0; + new (&temp->obj) rabbit::ObjectPtr; + temp->next = temp+1; + temp++; + } + bucks[n] = NULL; + temp->refs = 0; + new (&temp->obj) rabbit::ObjectPtr; + temp->next = NULL; + _freelist = nodes; + _nodes = nodes; + _buckets = bucks; + _slotused = 0; + _numofslots = size; +} \ No newline at end of file diff --git a/rabbit/RefTable.hpp b/rabbit/RefTable.hpp new file mode 100644 index 0000000..1d88095 --- /dev/null +++ b/rabbit/RefTable.hpp @@ -0,0 +1,42 @@ +/** + * @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 + +namespace rabbit { + class RefTable { + public: + class RefNode { + public: + rabbit::ObjectPtr obj; + uint64_t refs; + struct RefNode *next; + }; + RefTable(); + ~RefTable(); + void addRef(rabbit::Object &obj); + rabbit::Bool release(rabbit::Object &obj); + uint64_t getRefCount(rabbit::Object &obj); + void finalize(); + private: + RefNode *get(rabbit::Object &obj,rabbit::Hash &mainpos,RefNode **prev,bool add); + RefNode *add(rabbit::Hash mainpos,rabbit::Object &obj); + void resize(uint64_t size); + void allocNodes(uint64_t size); + uint64_t _numofslots; + uint64_t _slotused; + RefNode *_nodes; + RefNode *_freelist; + RefNode **_buckets; + }; +} + diff --git a/rabbit/SharedState.cpp b/rabbit/SharedState.cpp new file mode 100644 index 0000000..7e47b2e --- /dev/null +++ b/rabbit/SharedState.cpp @@ -0,0 +1,221 @@ +/** + * @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 + + + +static rabbit::Table *createDefaultDelegate(rabbit::SharedState *ss,const rabbit::RegFunction *funcz) +{ + int64_t i=0; + rabbit::Table *t=rabbit::Table::create(ss,0); + while(funcz[i].name!=0){ + SQNativeClosure *nc = SQNativeClosure::create(ss,funcz[i].f,0); + nc->_nparamscheck = funcz[i].nparamscheck; + nc->_name = rabbit::String::create(ss,funcz[i].name); + if(funcz[i].typemask && !compileTypemask(nc->_typecheck,funcz[i].typemask)) + return NULL; + t->newSlot(rabbit::String::create(ss,funcz[i].name),nc); + i++; + } + return t; +} + + + +rabbit::SharedState::SharedState() +{ + _compilererrorhandler = NULL; + _printfunc = NULL; + _errorfunc = NULL; + _debuginfo = false; + _notifyallexceptions = false; + _foreignptr = NULL; + _releasehook = NULL; +} + +#define newsysstring(s) { \ + _systemstrings->pushBack(rabbit::String::create(this,s)); \ + } + +#define newmetamethod(s) { \ + _metamethods->pushBack(rabbit::String::create(this,s)); \ + _table(_metamethodsmap)->newSlot(_metamethods->back(),(int64_t)(_metamethods->size()-1)); \ + } + +bool rabbit::compileTypemask(etk::Vector &res,const rabbit::Char *typemask) +{ + int64_t i = 0; + int64_t mask = 0; + while(typemask[i] != 0) { + switch(typemask[i]) { + case 'o': mask |= _RT_NULL; break; + case 'i': mask |= _RT_INTEGER; break; + case 'f': mask |= _RT_FLOAT; break; + case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break; + case 's': mask |= _RT_STRING; break; + case 't': mask |= _RT_TABLE; break; + case 'a': mask |= _RT_ARRAY; break; + case 'u': mask |= _RT_USERDATA; break; + case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break; + case 'b': mask |= _RT_BOOL; break; + case 'g': mask |= _RT_GENERATOR; break; + case 'p': mask |= _RT_USERPOINTER; break; + case 'v': mask |= _RT_THREAD; break; + case 'x': mask |= _RT_INSTANCE; break; + case 'y': mask |= _RT_CLASS; break; + case 'r': mask |= _RT_WEAKREF; break; + case '.': mask = -1; res.pushBack(mask); i++; mask = 0; continue; + case ' ': i++; continue; //ignores spaces + default: + return false; + } + i++; + if(typemask[i] == '|') { + i++; + if(typemask[i] == 0) + return false; + continue; + } + res.pushBack(mask); + mask = 0; + + } + return true; +} + + +void rabbit::SharedState::init() +{ + _scratchpad=NULL; + _scratchpadsize=0; + _stringtable = (rabbit::StringTable*)SQ_MALLOC(sizeof(rabbit::StringTable)); + new (_stringtable) rabbit::StringTable(this); + sq_new(_metamethods,etk::Vector); + sq_new(_systemstrings,etk::Vector); + sq_new(_types,etk::Vector); + _metamethodsmap = rabbit::Table::create(this,rabbit::MT_LAST-1); + //adding type strings to avoid memory trashing + //types names + newsysstring(_SC("null")); + newsysstring(_SC("table")); + newsysstring(_SC("array")); + newsysstring(_SC("closure")); + newsysstring(_SC("string")); + newsysstring(_SC("userdata")); + newsysstring(_SC("integer")); + newsysstring(_SC("float")); + newsysstring(_SC("userpointer")); + newsysstring(_SC("function")); + newsysstring(_SC("generator")); + newsysstring(_SC("thread")); + newsysstring(_SC("class")); + newsysstring(_SC("instance")); + newsysstring(_SC("bool")); + //meta methods + newmetamethod(MM_ADD); + newmetamethod(MM_SUB); + newmetamethod(MM_MUL); + newmetamethod(MM_DIV); + newmetamethod(MM_UNM); + newmetamethod(MM_MODULO); + newmetamethod(MM_SET); + newmetamethod(MM_GET); + newmetamethod(MM_TYPEOF); + newmetamethod(MM_NEXTI); + newmetamethod(MM_CMP); + newmetamethod(MM_CALL); + newmetamethod(MM_CLONED); + newmetamethod(MM_NEWSLOT); + newmetamethod(MM_DELSLOT); + newmetamethod(MM_TOSTRING); + newmetamethod(MM_NEWMEMBER); + newmetamethod(MM_INHERITED); + + _constructoridx = rabbit::String::create(this,_SC("constructor")); + _registry = rabbit::Table::create(this,0); + _consts = rabbit::Table::create(this,0); + _table_default_delegate = createDefaultDelegate(this,_table_default_delegate_funcz); + _array_default_delegate = createDefaultDelegate(this,_array_default_delegate_funcz); + _string_default_delegate = createDefaultDelegate(this,_string_default_delegate_funcz); + _number_default_delegate = createDefaultDelegate(this,_number_default_delegate_funcz); + _closure_default_delegate = createDefaultDelegate(this,_closure_default_delegate_funcz); + _generator_default_delegate = createDefaultDelegate(this,_generator_default_delegate_funcz); + _thread_default_delegate = createDefaultDelegate(this,_thread_default_delegate_funcz); + _class_default_delegate = createDefaultDelegate(this,_class_default_delegate_funcz); + _instance_default_delegate = createDefaultDelegate(this,_instance_default_delegate_funcz); + _weakref_default_delegate = createDefaultDelegate(this,_weakref_default_delegate_funcz); +} + +rabbit::SharedState::~SharedState() +{ + if(_releasehook) { + _releasehook(_foreignptr,0); + _releasehook = NULL; + } + _constructoridx.Null(); + _table(_registry)->finalize(); + _table(_consts)->finalize(); + _table(_metamethodsmap)->finalize(); + _registry.Null(); + _consts.Null(); + _metamethodsmap.Null(); + while(!_systemstrings->empty()) { + _systemstrings->back().Null(); + _systemstrings->popBack(); + } + _thread(_root_vm)->finalize(); + _root_vm.Null(); + _table_default_delegate.Null(); + _array_default_delegate.Null(); + _string_default_delegate.Null(); + _number_default_delegate.Null(); + _closure_default_delegate.Null(); + _generator_default_delegate.Null(); + _thread_default_delegate.Null(); + _class_default_delegate.Null(); + _instance_default_delegate.Null(); + _weakref_default_delegate.Null(); + _refs_table.finalize(); + using tmpType = etk::Vector; + sq_delete(_types, tmpType); + sq_delete(_systemstrings, tmpType); + sq_delete(_metamethods, tmpType); + sq_delete(_stringtable, rabbit::StringTable); + if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize); +} + + +int64_t rabbit::SharedState::getMetaMethodIdxByName(const rabbit::ObjectPtr &name) { + if(sq_type(name) != rabbit::OT_STRING) { + return -1; + } + rabbit::ObjectPtr ret; + if(_table(_metamethodsmap)->get(name,ret)) { + return _integer(ret); + } + return -1; +} + + +rabbit::Char* rabbit::SharedState::getScratchPad(int64_t size) { + int64_t newsize; + if(size>0) { + if(_scratchpadsize < size) { + newsize = size + (size>>1); + _scratchpad = (rabbit::Char *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); + _scratchpadsize = newsize; + } else if(_scratchpadsize >= (size<<5)) { + newsize = _scratchpadsize >> 1; + _scratchpad = (rabbit::Char *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); + _scratchpadsize = newsize; + } + } + return _scratchpad; +} diff --git a/rabbit/SharedState.hpp b/rabbit/SharedState.hpp new file mode 100644 index 0000000..d863460 --- /dev/null +++ b/rabbit/SharedState.hpp @@ -0,0 +1,85 @@ +/** + * @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 + +namespace rabbit { + class StringTable; + class RegFunction; + class SharedState { + public: + SharedState(); + ~SharedState(); + void init(); + public: + rabbit::Char* getScratchPad(int64_t size); + int64_t getMetaMethodIdxByName(const rabbit::ObjectPtr &name); + etk::Vector *_metamethods; + rabbit::ObjectPtr _metamethodsmap; + etk::Vector *_systemstrings; + etk::Vector *_types; + rabbit::StringTable *_stringtable; + RefTable _refs_table; + rabbit::ObjectPtr _registry; + rabbit::ObjectPtr _consts; + rabbit::ObjectPtr _constructoridx; + rabbit::ObjectPtr _root_vm; + rabbit::ObjectPtr _table_default_delegate; + static const rabbit::RegFunction _table_default_delegate_funcz[]; + rabbit::ObjectPtr _array_default_delegate; + static const rabbit::RegFunction _array_default_delegate_funcz[]; + rabbit::ObjectPtr _string_default_delegate; + static const rabbit::RegFunction _string_default_delegate_funcz[]; + rabbit::ObjectPtr _number_default_delegate; + static const rabbit::RegFunction _number_default_delegate_funcz[]; + rabbit::ObjectPtr _generator_default_delegate; + static const rabbit::RegFunction _generator_default_delegate_funcz[]; + rabbit::ObjectPtr _closure_default_delegate; + static const rabbit::RegFunction _closure_default_delegate_funcz[]; + rabbit::ObjectPtr _thread_default_delegate; + static const rabbit::RegFunction _thread_default_delegate_funcz[]; + rabbit::ObjectPtr _class_default_delegate; + static const rabbit::RegFunction _class_default_delegate_funcz[]; + rabbit::ObjectPtr _instance_default_delegate; + static const rabbit::RegFunction _instance_default_delegate_funcz[]; + rabbit::ObjectPtr _weakref_default_delegate; + static const rabbit::RegFunction _weakref_default_delegate_funcz[]; + + SQCOMPILERERROR _compilererrorhandler; + SQPRINTFUNCTION _printfunc; + SQPRINTFUNCTION _errorfunc; + bool _debuginfo; + bool _notifyallexceptions; + rabbit::UserPointer _foreignptr; + SQRELEASEHOOK _releasehook; + private: + rabbit::Char *_scratchpad; + int64_t _scratchpadsize; + }; + + #define _sp(s) (_sharedstate->getScratchPad(s)) + #define _spval (_sharedstate->getScratchPad(-1)) + + #define _table_ddel _table(_sharedstate->_table_default_delegate) + #define _array_ddel _table(_sharedstate->_array_default_delegate) + #define _string_ddel _table(_sharedstate->_string_default_delegate) + #define _number_ddel _table(_sharedstate->_number_default_delegate) + #define _generator_ddel _table(_sharedstate->_generator_default_delegate) + #define _closure_ddel _table(_sharedstate->_closure_default_delegate) + #define _thread_ddel _table(_sharedstate->_thread_default_delegate) + #define _class_ddel _table(_sharedstate->_class_default_delegate) + #define _instance_ddel _table(_sharedstate->_instance_default_delegate) + #define _weakref_ddel _table(_sharedstate->_weakref_default_delegate) + + bool compileTypemask(etk::Vector &res,const rabbit::Char *typemask); + +} + diff --git a/rabbit/String.cpp b/rabbit/String.cpp new file mode 100644 index 0000000..908b239 --- /dev/null +++ b/rabbit/String.cpp @@ -0,0 +1,45 @@ +/** + * @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 + + +rabbit::Hash rabbit::_hashstr(const rabbit::Char *s, size_t l); { + rabbit::Hash h = (rabbit::Hash)l; /* seed */ + size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */ + for (; l>=step; l-=step) + h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++)); + return h; +} + + +rabbit::String *rabbit::String::create(rabbit::SharedState *ss,const rabbit::Char *s,int64_t len) +{ + rabbit::String *str=ADD_STRING(ss,s,len); + return str; +} + +void rabbit::String::release() +{ + REMOVE_STRING(_sharedstate,this); +} + +int64_t rabbit::String::next(const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey, rabbit::ObjectPtr &outval) +{ + int64_t idx = (int64_t)translateIndex(refpos); + while(idx < _len){ + outkey = (int64_t)idx; + outval = (int64_t)((uint64_t)_val[idx]); + //return idx for the next iteration + return ++idx; + } + //nothing to iterate anymore + return -1; +} + diff --git a/rabbit/String.hpp b/rabbit/String.hpp new file mode 100644 index 0000000..6e7fc23 --- /dev/null +++ b/rabbit/String.hpp @@ -0,0 +1,32 @@ +/** + * @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 + +namespace rabbit { + + rabbit::Hash _hashstr (const rabbit::Char *s, size_t l); + class String : public rabbit::RefCounted { + String(){} + ~String(){} + public: + static rabbit::String *create(rabbit::SharedState *ss, const rabbit::Char *, int64_t len = -1 ); + int64_t next(const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey, rabbit::ObjectPtr &outval); + void release(); + rabbit::SharedState *_sharedstate; + rabbit::String *_next; //chain for the string table + int64_t _len; + rabbit::Hash _hash; + rabbit::Char _val[1]; + }; + + + +} + diff --git a/rabbit/StringTable.cpp b/rabbit/StringTable.cpp new file mode 100644 index 0000000..d4edab9 --- /dev/null +++ b/rabbit/StringTable.cpp @@ -0,0 +1,102 @@ +/** + * @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 + + + + +rabbit::StringTable::StringTable(rabbit::SharedState *ss) +{ + _sharedstate = ss; + allocNodes(4); + _slotused = 0; +} + +rabbit::StringTable::~StringTable() +{ + SQ_FREE(_strings,sizeof(rabbit::String*)*_numofslots); + _strings = NULL; +} + +void rabbit::StringTable::allocNodes(int64_t size) +{ + _numofslots = size; + _strings = (rabbit::String**)SQ_MALLOC(sizeof(rabbit::String*)*_numofslots); + memset(_strings,0,sizeof(rabbit::String*)*_numofslots); +} + +rabbit::String *rabbit::StringTable::add(const rabbit::Char *news,int64_t len) +{ + if(len<0) + len = (int64_t)scstrlen(news); + rabbit::Hash newhash = ::_hashstr(news,len); + rabbit::Hash h = newhash&(_numofslots-1); + rabbit::String *s; + for (s = _strings[h]; s; s = s->_next){ + if(s->_len == len && (!memcmp(news,s->_val,sq_rsl(len)))) + return s; //found + } + + rabbit::String *t = (rabbit::String *)SQ_MALLOC(sq_rsl(len)+sizeof(rabbit::String)); + new (t) rabbit::String; + t->_sharedstate = _sharedstate; + memcpy(t->_val,news,sq_rsl(len)); + t->_val[len] = _SC('\0'); + t->_len = len; + t->_hash = newhash; + t->_next = _strings[h]; + _strings[h] = t; + _slotused++; + if (_slotused > _numofslots) /* too crowded? */ + resize(_numofslots*2); + return t; +} + +void rabbit::StringTable::resize(int64_t size) +{ + int64_t oldsize=_numofslots; + rabbit::String **oldtable=_strings; + allocNodes(size); + for (int64_t i=0; i_next; + rabbit::Hash h = p->_hash&(_numofslots-1); + p->_next = _strings[h]; + _strings[h] = p; + p = next; + } + } + SQ_FREE(oldtable,oldsize*sizeof(rabbit::String*)); +} + +void rabbit::StringTable::remove(rabbit::String *bs) +{ + rabbit::String *s; + rabbit::String *prev=NULL; + rabbit::Hash h = bs->_hash&(_numofslots - 1); + + for (s = _strings[h]; s; ){ + if(s == bs){ + if(prev) + prev->_next = s->_next; + else + _strings[h] = s->_next; + _slotused--; + int64_t slen = s->_len; + s->~rabbit::String(); + SQ_FREE(s,sizeof(rabbit::String) + sq_rsl(slen)); + return; + } + prev = s; + s = s->_next; + } + assert(0);//if this fail something is wrong +} diff --git a/rabbit/StringTable.hpp b/rabbit/StringTable.hpp new file mode 100644 index 0000000..1cf536a --- /dev/null +++ b/rabbit/StringTable.hpp @@ -0,0 +1,33 @@ +/** + * @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 + +namespace rabbit { + + class StringTable { + public: + StringTable(rabbit::SharedState*ss); + ~StringTable(); + rabbit::String *add(const rabbit::Char *,int64_t len); + void remove(rabbit::String *); + private: + void resize(int64_t size); + void allocNodes(int64_t size); + rabbit::String **_strings; + uint64_t _numofslots; + uint64_t _slotused; + rabbit::SharedState *_sharedstate; + }; + + #define ADD_STRING(ss,str,len) ss->_stringtable->add(str,len) + #define REMOVE_STRING(ss,bstr) ss->_stringtable->remove(bstr) + +} + diff --git a/rabbit/sqtable.cpp b/rabbit/Table.cpp similarity index 63% rename from rabbit/sqtable.cpp rename to rabbit/Table.cpp index b5bbb10..f3248a8 100644 --- a/rabbit/sqtable.cpp +++ b/rabbit/Table.cpp @@ -5,17 +5,28 @@ * @copyright 2003-2017, Alberto DEMICHELIS, all right reserved * @license MPL-2 (see license file) */ +#pragma once + +#include + +rabbit::Hash rabbit::HashObj(const rabbit::ObjectPtr &key); { + switch(sq_type(key)) { + case rabbit::OT_STRING: + return _string(key)->_hash; + case rabbit::OT_FLOAT: + return (rabbit::Hash)((int64_t)_float(key)); + case rabbit::OT_BOOL: + case rabbit::OT_INTEGER: + return (rabbit::Hash)((int64_t)_integer(key)); + default: + return hashptr(key._unVal.pRefCounted); + } +} -#include -#include -#include -#include -#include #define MINPOWER2 4 -SQTable::SQTable(SQSharedState *ss,int64_t ninitialsize) -{ +rabbit::Table::rabbit::Table(rabbit::SharedState *ss,int64_t ninitialsize) { int64_t pow2size=MINPOWER2; while(ninitialsize>pow2size)pow2size=pow2size<<1; allocNodes(pow2size); @@ -23,9 +34,7 @@ SQTable::SQTable(SQSharedState *ss,int64_t ninitialsize) _delegate = NULL; } -void SQTable::remove(const rabbit::ObjectPtr &key) -{ - +void rabbit::Table::remove(const rabbit::ObjectPtr &key) { _HashNode *n = _get(key, HashObj(key) & (_numofnodes - 1)); if (n) { n->val.Null(); @@ -35,7 +44,7 @@ void SQTable::remove(const rabbit::ObjectPtr &key) } } -void SQTable::allocNodes(int64_t nsize) +void rabbit::Table::allocNodes(int64_t nsize) { _HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nsize); for(int64_t i=0;i_nodes; @@ -110,7 +119,7 @@ SQTable *SQTable::clone() return nt; } -bool SQTable::get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val) +bool rabbit::Table::get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val) { if(sq_type(key) == rabbit::OT_NULL) return false; @@ -121,10 +130,10 @@ bool SQTable::get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val) } return false; } -bool SQTable::newSlot(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val) +bool rabbit::Table::newSlot(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val) { assert(sq_type(key) != rabbit::OT_NULL); - SQHash h = HashObj(key) & (_numofnodes - 1); + rabbit::Hash h = HashObj(key) & (_numofnodes - 1); _HashNode *n = _get(key, h); if (n) { n->val = val; @@ -139,7 +148,7 @@ bool SQTable::newSlot(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val) if(sq_type(mp->key) != rabbit::OT_NULL) { n = _firstfree; /* get a free place */ - SQHash mph = HashObj(mp->key) & (_numofnodes - 1); + rabbit::Hash mph = HashObj(mp->key) & (_numofnodes - 1); _HashNode *othern; /* main position of colliding node */ if (mp > n && (othern = &_nodes[mph]) != mp){ @@ -178,7 +187,7 @@ bool SQTable::newSlot(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val) return newSlot(key, val); } -int64_t SQTable::next(bool getweakrefs,const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey, rabbit::ObjectPtr &outval) +int64_t rabbit::Table::next(bool getweakrefs,const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey, rabbit::ObjectPtr &outval) { int64_t idx = (int64_t)translateIndex(refpos); while (idx < _numofnodes) { @@ -197,7 +206,7 @@ int64_t SQTable::next(bool getweakrefs,const rabbit::ObjectPtr &refpos, rabbit:: } -bool SQTable::set(const rabbit::ObjectPtr &key, const rabbit::ObjectPtr &val) +bool rabbit::Table::set(const rabbit::ObjectPtr &key, const rabbit::ObjectPtr &val) { _HashNode *n = _get(key, HashObj(key) & (_numofnodes - 1)); if (n) { @@ -207,20 +216,72 @@ bool SQTable::set(const rabbit::ObjectPtr &key, const rabbit::ObjectPtr &val) return false; } -void SQTable::_clearNodes() +void rabbit::Table::_clearNodes() { for(int64_t i = 0;i < _numofnodes; i++) { _HashNode &n = _nodes[i]; n.key.Null(); n.val.Null(); } } -void SQTable::finalize() +void rabbit::Table::finalize() { _clearNodes(); setDelegate(NULL); } -void SQTable::clear() +void rabbit::Table::clear() { _clearNodes(); _usednodes = 0; Rehash(true); } + + +rabbit::Table* rabbit::Table::create(rabbit::SharedState *ss,int64_t ninitialsize) +{ + char* tmp = (char*)SQ_MALLOC(sizeof(rabbit::Table)); + rabbit::Table *newtable = new (tmp) rabbit::Table(ss, ninitialsize); + newtable->_delegate = NULL; + return newtable; +} + +rabbit::Table::~Table() { + setDelegate(NULL); + for (int64_t i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode(); + SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode)); +} + +_HashNode* rabbit::Table::_get(const rabbit::ObjectPtr &key,rabbit::Hash hash) { + _HashNode *n = &_nodes[hash]; + do { + if( _rawval(n->key) == _rawval(key) + && sq_type(n->key) == sq_type(key)){ + return n; + } + } while((n = n->next)); + return NULL; +} + +//for compiler use +bool rabbit::Table::getStr(const rabbit::Char* key,int64_t keylen,rabbit::ObjectPtr &val) { + rabbit::Hash hash = _hashstr(key,keylen); + _HashNode *n = &_nodes[hash & (_numofnodes - 1)]; + _HashNode *res = NULL; + do{ + if(sq_type(n->key) == rabbit::OT_STRING && (scstrcmp(_stringval(n->key),key) == 0)){ + res = n; + break; + } + }while((n = n->next)); + if (res) { + val = _realval(res->val); + return true; + } + return false; +} + +int64_t rabbit::Table::countUsed() { + return _usednodes; +} + +void rabbit::Table::release() { + sq_delete(this, rabbit::Table); +} diff --git a/rabbit/Table.hpp b/rabbit/Table.hpp new file mode 100644 index 0000000..239ed85 --- /dev/null +++ b/rabbit/Table.hpp @@ -0,0 +1,55 @@ +/** + * @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 + +namespace rabbit { + class SharedState; + + #define hashptr(p) ((rabbit::Hash)(((int64_t)p) >> 3)) + + rabbit::Hash HashObj(const rabbit::ObjectPtr &key); + + class Table : public rabbit::Delegable { + private: + struct _HashNode { + _HashNode() { next = NULL; } + rabbit::ObjectPtr val; + rabbit::ObjectPtr key; + _HashNode *next; + }; + _HashNode *_firstfree; + _HashNode *_nodes; + int64_t _numofnodes; + int64_t _usednodes; + void allocNodes(int64_t nsize); + void Rehash(bool force); + Table(rabbit::SharedState *ss, int64_t ninitialsize); + void _clearNodes(); + public: + static rabbit::Table* create(rabbit::SharedState *ss,int64_t ninitialsize); + void finalize(); + Table *clone(); + ~Table(); + _HashNode *_get(const rabbit::ObjectPtr &key,rabbit::Hash hash); + //for compiler use + bool getStr(const rabbit::Char* key,int64_t keylen,rabbit::ObjectPtr &val); + bool get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val); + void remove(const rabbit::ObjectPtr &key); + bool set(const rabbit::ObjectPtr &key, const rabbit::ObjectPtr &val); + //returns true if a new slot has been created false if it was already present + bool newSlot(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val); + int64_t next(bool getweakrefs,const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey, rabbit::ObjectPtr &outval); + int64_t countUsed(); + void clear(); + void release(); + }; +} + diff --git a/rabbit/UserData.hpp b/rabbit/UserData.hpp index 4f57ea8..ee74103 100644 --- a/rabbit/UserData.hpp +++ b/rabbit/UserData.hpp @@ -10,14 +10,14 @@ namespace rabbit { class UserData : public rabbit::Delegable { public: - UserData(SQSharedState *ss) { + UserData(rabbit::SharedState *ss) { _delegate = 0; m_hook = NULL; } ~UserData() { setDelegate(NULL); } - static UserData* create(SQSharedState *ss, int64_t size) { + static UserData* create(rabbit::SharedState *ss, int64_t size) { UserData* ud = (UserData*)SQ_MALLOC(sq_aligning(sizeof(UserData))+size); new (ud) UserData(ss); ud->m_size = size; diff --git a/rabbit/VirtualMachine.cpp b/rabbit/VirtualMachine.cpp index 1866fd4..1a0664a 100644 --- a/rabbit/VirtualMachine.cpp +++ b/rabbit/VirtualMachine.cpp @@ -12,8 +12,8 @@ #include #include #include -#include -#include + + #include #include #include @@ -112,7 +112,7 @@ bool rabbit::VirtualMachine::ARITH_OP(uint64_t op,rabbit::ObjectPtr &trg,const r return true; } -rabbit::VirtualMachine::VirtualMachine(SQSharedState *ss) +rabbit::VirtualMachine::VirtualMachine(rabbit::SharedState *ss) { _sharedstate=ss; _suspended = SQFalse; @@ -319,7 +319,7 @@ bool rabbit::VirtualMachine::toString(const rabbit::ObjectPtr &o,rabbit::ObjectP default: scsprintf(_sp(sq_rsl((sizeof(void*)*2)+NUMBER_MAX_CHAR)),sq_rsl((sizeof(void*)*2)+NUMBER_MAX_CHAR),_SC("(%s : 0x%p)"),getTypeName(o),(void*)_rawval(o)); } - res = SQString::create(_get_shared_state(this),_spval); + res = rabbit::String::create(_get_shared_state(this),_spval); return true; } @@ -333,7 +333,7 @@ bool rabbit::VirtualMachine::stringCat(const rabbit::ObjectPtr &str,const rabbit rabbit::Char *s = _sp(sq_rsl(l + ol + 1)); memcpy(s, _stringval(a), sq_rsl(l)); memcpy(s + l, _stringval(b), sq_rsl(ol)); - dest = SQString::create(_get_shared_state(this), _spval, l + ol); + dest = rabbit::String::create(_get_shared_state(this), _spval, l + ol); return true; } @@ -346,7 +346,7 @@ bool rabbit::VirtualMachine::typeOf(const rabbit::ObjectPtr &obj1,rabbit::Object return callMetaMethod(closure,MT_TYPEOF,1,dest); } } - dest = SQString::create(_get_shared_state(this),getTypeName(obj1)); + dest = rabbit::String::create(_get_shared_state(this),getTypeName(obj1)); return true; } @@ -360,7 +360,7 @@ bool rabbit::VirtualMachine::init(rabbit::VirtualMachine *friendvm, int64_t stac _stackbase = 0; _top = 0; if(!friendvm) { - _roottable = SQTable::create(_get_shared_state(this), 0); + _roottable = rabbit::Table::create(_get_shared_state(this), 0); sq_base_register(this); } else { @@ -901,7 +901,7 @@ exception_restore: continue; case _OP_NEWOBJ: switch(arg3) { - case NOT_TABLE: TARGET = SQTable::create(_get_shared_state(this), arg1); continue; + case NOT_TABLE: TARGET = rabbit::Table::create(_get_shared_state(this), arg1); continue; case NOT_ARRAY: TARGET = rabbit::Array::create(_get_shared_state(this), 0); _array(TARGET)->reserve(arg1); continue; case NOT_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue; default: assert(0); continue; @@ -1294,7 +1294,7 @@ bool rabbit::VirtualMachine::get(const rabbit::ObjectPtr &self, const rabbit::Ob bool rabbit::VirtualMachine::invokeDefaultDelegate(const rabbit::ObjectPtr &self,const rabbit::ObjectPtr &key,rabbit::ObjectPtr &dest) { - SQTable *ddel = NULL; + rabbit::Table *ddel = NULL; switch(sq_type(self)) { case rabbit::OT_CLASS: ddel = _class_ddel; break; case rabbit::OT_TABLE: ddel = _table_ddel; break; diff --git a/rabbit/VirtualMachine.hpp b/rabbit/VirtualMachine.hpp index 3e43dcf..98ff432 100644 --- a/rabbit/VirtualMachine.hpp +++ b/rabbit/VirtualMachine.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #define MAX_NATIVE_CALLS 100 @@ -58,7 +59,7 @@ namespace rabbit { ET_RESUME_VM, ET_RESUME_THROW_VM }; - VirtualMachine(SQSharedState *ss); + VirtualMachine(rabbit::SharedState *ss); ~VirtualMachine(); bool init(VirtualMachine *friendvm, int64_t stacksize); bool execute(rabbit::ObjectPtr &func, int64_t nargs, int64_t stackbase, rabbit::ObjectPtr &outres, rabbit::Bool raiseerror, ExecutionType et = ET_CALL); @@ -87,7 +88,7 @@ namespace rabbit { bool stringCat(const rabbit::ObjectPtr &str, const rabbit::ObjectPtr &obj, rabbit::ObjectPtr &dest); static bool isEqual(const rabbit::ObjectPtr &o1,const rabbit::ObjectPtr &o2,bool &res); bool toString(const rabbit::ObjectPtr &o,rabbit::ObjectPtr &res); - SQString *printObjVal(const rabbit::ObjectPtr &o); + rabbit::String *printObjVal(const rabbit::ObjectPtr &o); void raise_error(const rabbit::Char *s, ...); @@ -172,7 +173,7 @@ namespace rabbit { callInfo *ci; rabbit::UserPointer _foreignptr; //VMs sharing the same state - SQSharedState *_sharedstate; + rabbit::SharedState *_sharedstate; int64_t _nnativecalls; int64_t _nmetamethodscall; SQRELEASEHOOK _releasehook; diff --git a/rabbit/rabbit.hpp b/rabbit/rabbit.hpp index 1bd8aca..16ad727 100644 --- a/rabbit/rabbit.hpp +++ b/rabbit/rabbit.hpp @@ -28,19 +28,20 @@ #include "sqconfig.hpp" -#define RABBIT_VERSION _SC("Rabbit 0.1 un-stable") +#define RABBIT_VERSION _SC("Rabbit 0.1 un-stable") #define RABBIT_COPYRIGHT _SC("Copyright (C) 2003-2017 Alberto Demichelis") -#define RABBIT_AUTHOR _SC("Edouard DUPIN") +#define RABBIT_AUTHOR _SC("Edouard DUPIN") #define RABBIT_VERSION_NUMBER 010 -#define SQ_VMSTATE_IDLE 0 -#define SQ_VMSTATE_RUNNING 1 -#define SQ_VMSTATE_SUSPENDED 2 +#define SQ_VMSTATE_IDLE 0 +#define SQ_VMSTATE_RUNNING 1 +#define SQ_VMSTATE_SUSPENDED 2 #define RABBIT_EOB 0 #define SQ_BYTECODE_STREAM_TAG 0xFAFA #include +#include @@ -114,7 +115,7 @@ RABBIT_API void sq_pushthread(rabbit::VirtualMachine* v, rabbit::VirtualMachine* RABBIT_API rabbit::ObjectType sq_gettype(rabbit::VirtualMachine* v,int64_t idx); RABBIT_API rabbit::Result sq_typeof(rabbit::VirtualMachine* v,int64_t idx); RABBIT_API int64_t sq_getsize(rabbit::VirtualMachine* v,int64_t idx); -RABBIT_API SQHash sq_gethash(rabbit::VirtualMachine* v, int64_t idx); +RABBIT_API rabbit::Hash sq_gethash(rabbit::VirtualMachine* v, int64_t idx); RABBIT_API rabbit::Result sq_getbase(rabbit::VirtualMachine* v,int64_t idx); RABBIT_API rabbit::Bool sq_instanceof(rabbit::VirtualMachine* v); RABBIT_API rabbit::Result sq_tostring(rabbit::VirtualMachine* v,int64_t idx); diff --git a/rabbit/sqapi.cpp b/rabbit/sqapi.cpp index 8b1362b..96b1ba7 100644 --- a/rabbit/sqapi.cpp +++ b/rabbit/sqapi.cpp @@ -7,8 +7,8 @@ */ #include #include -#include -#include + + #include #include #include @@ -47,8 +47,8 @@ int64_t sq_aux_invalidtype(rabbit::VirtualMachine* v,rabbit::ObjectType type) rabbit::VirtualMachine* sq_open(int64_t initialstacksize) { - SQSharedState *ss; - sq_new(ss, SQSharedState); + rabbit::SharedState *ss; + sq_new(ss, rabbit::SharedState); ss->init(); char* allocatedData = (char*)SQ_MALLOC(sizeof(rabbit::VirtualMachine)); @@ -67,7 +67,7 @@ rabbit::VirtualMachine* sq_open(int64_t initialstacksize) rabbit::VirtualMachine* sq_newthread(rabbit::VirtualMachine* friendvm, int64_t initialstacksize) { - SQSharedState *ss; + rabbit::SharedState *ss; ss=_get_shared_state(friendvm); char* allocatedData = (char*)SQ_MALLOC(sizeof(rabbit::VirtualMachine)); @@ -123,9 +123,9 @@ void sq_setdebughook(rabbit::VirtualMachine* v) void sq_close(rabbit::VirtualMachine* v) { - SQSharedState *ss = _get_shared_state(v); + rabbit::SharedState *ss = _get_shared_state(v); _thread(ss->_root_vm)->finalize(); - sq_delete(ss, SQSharedState); + sq_delete(ss, rabbit::SharedState); } int64_t sq_getversion() @@ -231,7 +231,7 @@ void sq_pushnull(rabbit::VirtualMachine* v) void sq_pushstring(rabbit::VirtualMachine* v,const rabbit::Char *s,int64_t len) { if(s) - v->push(rabbit::ObjectPtr(SQString::create(_get_shared_state(v), s, len))); + v->push(rabbit::ObjectPtr(rabbit::String::create(_get_shared_state(v), s, len))); else v->pushNull(); } @@ -269,12 +269,12 @@ rabbit::UserPointer sq_newuserdata(rabbit::VirtualMachine* v,uint64_t size) void sq_newtable(rabbit::VirtualMachine* v) { - v->push(SQTable::create(_get_shared_state(v), 0)); + v->push(rabbit::Table::create(_get_shared_state(v), 0)); } void sq_newtableex(rabbit::VirtualMachine* v,int64_t initialcapacity) { - v->push(SQTable::create(_get_shared_state(v), initialcapacity)); + v->push(rabbit::Table::create(_get_shared_state(v), initialcapacity)); } void sq_newarray(rabbit::VirtualMachine* v,int64_t size) @@ -420,7 +420,7 @@ rabbit::Result sq_setnativeclosurename(rabbit::VirtualMachine* v,int64_t idx,con rabbit::Object o = stack_get(v, idx); if(sq_isnativeclosure(o)) { SQNativeClosure *nc = _nativeclosure(o); - nc->_name = SQString::create(_get_shared_state(v),name); + nc->_name = rabbit::String::create(_get_shared_state(v),name); return SQ_OK; } return sq_throwerror(v,_SC("the object is not a nativeclosure")); @@ -737,7 +737,7 @@ int64_t sq_getsize(rabbit::VirtualMachine* v, int64_t idx) } } -SQHash sq_gethash(rabbit::VirtualMachine* v, int64_t idx) +rabbit::Hash sq_gethash(rabbit::VirtualMachine* v, int64_t idx) { rabbit::ObjectPtr &o = stack_get(v, idx); return HashObj(o); @@ -1133,7 +1133,7 @@ void sq_resetobject(rabbit::Object *po) rabbit::Result sq_throwerror(rabbit::VirtualMachine* v,const rabbit::Char *err) { - v->_lasterror=SQString::create(_get_shared_state(v),err); + v->_lasterror=rabbit::String::create(_get_shared_state(v),err); return SQ_ERROR; } @@ -1446,7 +1446,7 @@ rabbit::Result sq_getmemberhandle(rabbit::VirtualMachine* v,int64_t idx,rabbit:: rabbit::ObjectPtr *o = NULL; _GETSAFE_OBJ(v, idx, rabbit::OT_CLASS,o); rabbit::ObjectPtr &key = stack_get(v,-1); - SQTable *m = _class(*o)->_members; + rabbit::Table *m = _class(*o)->_members; rabbit::ObjectPtr val; if(m->get(key,val)) { handle->_static = _isfield(val) ? SQFalse : SQTrue; @@ -1561,7 +1561,7 @@ rabbit::Result sq_getweakrefval(rabbit::VirtualMachine* v,int64_t idx) rabbit::Result sq_getdefaultdelegate(rabbit::VirtualMachine* v,rabbit::ObjectType t) { - SQSharedState *ss = _get_shared_state(v); + rabbit::SharedState *ss = _get_shared_state(v); switch(t) { case rabbit::OT_TABLE: v->push(ss->_table_default_delegate); break; case rabbit::OT_ARRAY: v->push(ss->_array_default_delegate); break; diff --git a/rabbit/sqbaselib.cpp b/rabbit/sqbaselib.cpp index 666cee2..f2ed8ff 100644 --- a/rabbit/sqbaselib.cpp +++ b/rabbit/sqbaselib.cpp @@ -7,8 +7,8 @@ */ #include #include -#include -#include + + #include #include #include @@ -258,7 +258,7 @@ static int64_t base_array(rabbit::VirtualMachine* v) static int64_t base_type(rabbit::VirtualMachine* v) { rabbit::ObjectPtr &o = stack_get(v,2); - v->push(SQString::create(_get_shared_state(v),getTypeName(o),-1)); + v->push(rabbit::String::create(_get_shared_state(v),getTypeName(o),-1)); return 1; } @@ -411,7 +411,7 @@ static int64_t number_delegate_tochar(rabbit::VirtualMachine* v) { rabbit::Object &o=stack_get(v,1); rabbit::Char c = (rabbit::Char)tointeger(o); - v->push(SQString::create(_get_shared_state(v),(const rabbit::Char *)&c,1)); + v->push(rabbit::String::create(_get_shared_state(v),(const rabbit::Char *)&c,1)); return 1; } @@ -465,8 +465,8 @@ static int64_t table_getdelegate(rabbit::VirtualMachine* v) static int64_t table_filter(rabbit::VirtualMachine* v) { rabbit::Object &o = stack_get(v,1); - SQTable *tbl = _table(o); - rabbit::ObjectPtr ret = SQTable::create(_get_shared_state(v),0); + rabbit::Table *tbl = _table(o); + rabbit::ObjectPtr ret = rabbit::Table::create(_get_shared_state(v),0); rabbit::ObjectPtr itr, key, val; int64_t nitr; @@ -490,7 +490,7 @@ static int64_t table_filter(rabbit::VirtualMachine* v) } -const rabbit::RegFunction SQSharedState::_table_default_delegate_funcz[]={ +const rabbit::RegFunction rabbit::SharedState::_table_default_delegate_funcz[]={ {_SC("len"),default_delegate_len,1, _SC("t")}, {_SC("rawget"),container_rawget,2, _SC("t")}, {_SC("rawset"),container_rawset,3, _SC("t")}, @@ -809,7 +809,7 @@ static int64_t array_slice(rabbit::VirtualMachine* v) } -const rabbit::RegFunction SQSharedState::_array_default_delegate_funcz[]={ +const rabbit::RegFunction rabbit::SharedState::_array_default_delegate_funcz[]={ {_SC("len"),default_delegate_len,1, _SC("a")}, {_SC("append"),array_append,2, _SC("a")}, {_SC("extend"),array_extend,2, _SC("aa")}, @@ -844,7 +844,7 @@ static int64_t string_slice(rabbit::VirtualMachine* v) if(eidx < 0)eidx = slen + eidx; if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes")); if(eidx > slen || sidx < 0) return sq_throwerror(v, _SC("slice out of range")); - v->push(SQString::create(_get_shared_state(v),&_stringval(o)[sidx],eidx-sidx)); + v->push(rabbit::String::create(_get_shared_state(v),&_stringval(o)[sidx],eidx-sidx)); return 1; } @@ -881,7 +881,7 @@ static int64_t string_find(rabbit::VirtualMachine* v) rabbit::Char *snew=(_get_shared_state(v)->getScratchPad(sq_rsl(len))); \ memcpy(snew,sthis,sq_rsl(len));\ for(int64_t i=sidx;ipush(SQString::create(_get_shared_state(v),snew,len)); \ + v->push(rabbit::String::create(_get_shared_state(v),snew,len)); \ return 1; \ } @@ -889,7 +889,7 @@ static int64_t string_find(rabbit::VirtualMachine* v) STRING_TOFUNCZ(tolower) STRING_TOFUNCZ(toupper) -const rabbit::RegFunction SQSharedState::_string_default_delegate_funcz[]={ +const rabbit::RegFunction rabbit::SharedState::_string_default_delegate_funcz[]={ {_SC("len"),default_delegate_len,1, _SC("s")}, {_SC("tointeger"),default_delegate_tointeger,-1, _SC("sn")}, {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")}, @@ -903,7 +903,7 @@ const rabbit::RegFunction SQSharedState::_string_default_delegate_funcz[]={ }; //INTEGER DEFAULT DELEGATE////////////////////////// -const rabbit::RegFunction SQSharedState::_number_default_delegate_funcz[]={ +const rabbit::RegFunction rabbit::SharedState::_number_default_delegate_funcz[]={ {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")}, {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")}, {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, @@ -970,7 +970,7 @@ static int64_t closure_setroot(rabbit::VirtualMachine* v) static int64_t closure_getinfos(rabbit::VirtualMachine* v) { rabbit::Object o = stack_get(v,1); - SQTable *res = SQTable::create(_get_shared_state(v),4); + rabbit::Table *res = rabbit::Table::create(_get_shared_state(v),4); if(sq_type(o) == rabbit::OT_CLOSURE) { SQFunctionProto *f = _closure(o)->_function; int64_t nparams = f->_nparameters + (f->_varparams?1:0); @@ -983,20 +983,20 @@ static int64_t closure_getinfos(rabbit::VirtualMachine* v) { _array(defparams)->set((int64_t)j,_closure(o)->_defaultparams[j]); } if(f->_varparams) { - _array(params)->set(nparams-1,SQString::create(_get_shared_state(v),_SC("..."),-1)); + _array(params)->set(nparams-1,rabbit::String::create(_get_shared_state(v),_SC("..."),-1)); } - res->newSlot(SQString::create(_get_shared_state(v),_SC("native"),-1),false); - res->newSlot(SQString::create(_get_shared_state(v),_SC("name"),-1),f->_name); - res->newSlot(SQString::create(_get_shared_state(v),_SC("src"),-1),f->_sourcename); - res->newSlot(SQString::create(_get_shared_state(v),_SC("parameters"),-1),params); - res->newSlot(SQString::create(_get_shared_state(v),_SC("varargs"),-1),f->_varparams); - res->newSlot(SQString::create(_get_shared_state(v),_SC("defparams"),-1),defparams); + res->newSlot(rabbit::String::create(_get_shared_state(v),_SC("native"),-1),false); + res->newSlot(rabbit::String::create(_get_shared_state(v),_SC("name"),-1),f->_name); + res->newSlot(rabbit::String::create(_get_shared_state(v),_SC("src"),-1),f->_sourcename); + res->newSlot(rabbit::String::create(_get_shared_state(v),_SC("parameters"),-1),params); + res->newSlot(rabbit::String::create(_get_shared_state(v),_SC("varargs"),-1),f->_varparams); + res->newSlot(rabbit::String::create(_get_shared_state(v),_SC("defparams"),-1),defparams); } else { //rabbit::OT_NATIVECLOSURE SQNativeClosure *nc = _nativeclosure(o); - res->newSlot(SQString::create(_get_shared_state(v),_SC("native"),-1),true); - res->newSlot(SQString::create(_get_shared_state(v),_SC("name"),-1),nc->_name); - res->newSlot(SQString::create(_get_shared_state(v),_SC("paramscheck"),-1),nc->_nparamscheck); + res->newSlot(rabbit::String::create(_get_shared_state(v),_SC("native"),-1),true); + res->newSlot(rabbit::String::create(_get_shared_state(v),_SC("name"),-1),nc->_name); + res->newSlot(rabbit::String::create(_get_shared_state(v),_SC("paramscheck"),-1),nc->_nparamscheck); rabbit::ObjectPtr typecheck; if(nc->_typecheck.size() > 0) { typecheck = @@ -1005,7 +1005,7 @@ static int64_t closure_getinfos(rabbit::VirtualMachine* v) { _array(typecheck)->set((int64_t)n,nc->_typecheck[n]); } } - res->newSlot(SQString::create(_get_shared_state(v),_SC("typecheck"),-1),typecheck); + res->newSlot(rabbit::String::create(_get_shared_state(v),_SC("typecheck"),-1),typecheck); } v->push(res); return 1; @@ -1013,7 +1013,7 @@ static int64_t closure_getinfos(rabbit::VirtualMachine* v) { -const rabbit::RegFunction SQSharedState::_closure_default_delegate_funcz[]={ +const rabbit::RegFunction rabbit::SharedState::_closure_default_delegate_funcz[]={ {_SC("call"),closure_call,-1, _SC("c")}, {_SC("pcall"),closure_pcall,-1, _SC("c")}, {_SC("acall"),closure_acall,2, _SC("ca")}, @@ -1032,14 +1032,14 @@ static int64_t generator_getstatus(rabbit::VirtualMachine* v) { rabbit::Object &o=stack_get(v,1); switch(_generator(o)->_state){ - case SQGenerator::eSuspended:v->push(SQString::create(_get_shared_state(v),_SC("suspended")));break; - case SQGenerator::eRunning:v->push(SQString::create(_get_shared_state(v),_SC("running")));break; - case SQGenerator::eDead:v->push(SQString::create(_get_shared_state(v),_SC("dead")));break; + case SQGenerator::eSuspended:v->push(rabbit::String::create(_get_shared_state(v),_SC("suspended")));break; + case SQGenerator::eRunning:v->push(rabbit::String::create(_get_shared_state(v),_SC("running")));break; + case SQGenerator::eDead:v->push(rabbit::String::create(_get_shared_state(v),_SC("dead")));break; } return 1; } -const rabbit::RegFunction SQSharedState::_generator_default_delegate_funcz[]={ +const rabbit::RegFunction rabbit::SharedState::_generator_default_delegate_funcz[]={ {_SC("getstatus"),generator_getstatus,1, _SC("g")}, {_SC("weakref"),obj_delegate_weakref,1, NULL }, {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, @@ -1195,7 +1195,7 @@ static int64_t thread_getstackinfos(rabbit::VirtualMachine* v) return sq_throwerror(v,_SC("wrong parameter")); } -const rabbit::RegFunction SQSharedState::_thread_default_delegate_funcz[] = { +const rabbit::RegFunction rabbit::SharedState::_thread_default_delegate_funcz[] = { {_SC("call"), thread_call, -1, _SC("v")}, {_SC("wakeup"), thread_wakeup, -1, _SC("v")}, {_SC("wakeupthrow"), thread_wakeupthrow, -2, _SC("v.b")}, @@ -1258,7 +1258,7 @@ static int64_t class_rawnewmember(rabbit::VirtualMachine* v) return SQ_SUCCEEDED(sq_rawnewmember(v,-4,bstatic))?1:SQ_ERROR; } -const rabbit::RegFunction SQSharedState::_class_default_delegate_funcz[] = { +const rabbit::RegFunction rabbit::SharedState::_class_default_delegate_funcz[] = { {_SC("getattributes"), class_getattributes, 2, _SC("y.")}, {_SC("setattributes"), class_setattributes, 3, _SC("y..")}, {_SC("rawget"),container_rawget,2, _SC("y")}, @@ -1281,7 +1281,7 @@ static int64_t instance_getclass(rabbit::VirtualMachine* v) return SQ_ERROR; } -const rabbit::RegFunction SQSharedState::_instance_default_delegate_funcz[] = { +const rabbit::RegFunction rabbit::SharedState::_instance_default_delegate_funcz[] = { {_SC("getclass"), instance_getclass, 1, _SC("x")}, {_SC("rawget"),container_rawget,2, _SC("x")}, {_SC("rawset"),container_rawset,3, _SC("x")}, @@ -1298,7 +1298,7 @@ static int64_t weakref_ref(rabbit::VirtualMachine* v) return 1; } -const rabbit::RegFunction SQSharedState::_weakref_default_delegate_funcz[] = { +const rabbit::RegFunction rabbit::SharedState::_weakref_default_delegate_funcz[] = { {_SC("ref"),weakref_ref,1, _SC("r")}, {_SC("weakref"),obj_delegate_weakref,1, NULL }, {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, diff --git a/rabbit/sqclosure.hpp b/rabbit/sqclosure.hpp index a317067..a875ed7 100644 --- a/rabbit/sqclosure.hpp +++ b/rabbit/sqclosure.hpp @@ -16,14 +16,14 @@ struct SQFunctionProto; struct SQClosure : public rabbit::RefCounted { private: - SQClosure(SQSharedState *ss,SQFunctionProto *func){ + SQClosure(rabbit::SharedState *ss,SQFunctionProto *func){ _function = func; __ObjaddRef(_function); _base = NULL; _env = NULL; _root=NULL; } public: - static SQClosure *create(SQSharedState *ss,SQFunctionProto *func,rabbit::WeakRef *root){ + static SQClosure *create(rabbit::SharedState *ss,SQFunctionProto *func,rabbit::WeakRef *root){ int64_t size = _CALC_CLOSURE_SIZE(func); SQClosure *nc=(SQClosure*)SQ_MALLOC(size); new (nc) SQClosure(ss,func); @@ -77,13 +77,13 @@ struct SQOuter : public rabbit::RefCounted { private: - SQOuter(SQSharedState *ss, rabbit::ObjectPtr *outer){ + SQOuter(rabbit::SharedState *ss, rabbit::ObjectPtr *outer){ _valptr = outer; _next = NULL; } public: - static SQOuter *create(SQSharedState *ss, rabbit::ObjectPtr *outer) + static SQOuter *create(rabbit::SharedState *ss, rabbit::ObjectPtr *outer) { SQOuter *nc = (SQOuter*)SQ_MALLOC(sizeof(SQOuter)); new (nc) SQOuter(ss, outer); @@ -110,13 +110,13 @@ struct SQGenerator : public rabbit::RefCounted { enum SQGeneratorState{eRunning,eSuspended,eDead}; private: - SQGenerator(SQSharedState *ss,SQClosure *closure){ + SQGenerator(rabbit::SharedState *ss,SQClosure *closure){ _closure=closure; _state=eRunning; _ci._generator=NULL; } public: - static SQGenerator *create(SQSharedState *ss,SQClosure *closure){ + static SQGenerator *create(rabbit::SharedState *ss,SQClosure *closure){ SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator)); new (nc) SQGenerator(ss,closure); return nc; @@ -147,12 +147,12 @@ public: struct SQNativeClosure : public rabbit::RefCounted { private: - SQNativeClosure(SQSharedState *ss,SQFUNCTION func){ + SQNativeClosure(rabbit::SharedState *ss,SQFUNCTION func){ _function=func; _env = NULL; } public: - static SQNativeClosure *create(SQSharedState *ss,SQFUNCTION func,int64_t nouters) + static SQNativeClosure *create(rabbit::SharedState *ss,SQFUNCTION func,int64_t nouters) { int64_t size = _CALC_NATVIVECLOSURE_SIZE(nouters); SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(size); diff --git a/rabbit/sqcompiler.cpp b/rabbit/sqcompiler.cpp index 8288adf..dde90d8 100644 --- a/rabbit/sqcompiler.cpp +++ b/rabbit/sqcompiler.cpp @@ -10,13 +10,13 @@ #include #include #include -#include + #include #include #include #include #include -#include + #define EXPR 1 #define OBJECT 2 @@ -80,7 +80,7 @@ public: { _vm=v; _lex.init(_get_shared_state(v), rg, up,Throwerror,this); - _sourcename = SQString::create(_get_shared_state(v), sourcename); + _sourcename = rabbit::String::create(_get_shared_state(v), sourcename); _lineinfo = lineinfo;_raiseerror = raiseerror; _scope.outers = 0; _scope.stacksize = 0; @@ -171,7 +171,7 @@ public: _debugop = 0; SQFuncState funcstate(_get_shared_state(_vm), NULL,Throwerror,this); - funcstate._name = SQString::create(_get_shared_state(_vm), _SC("main")); + funcstate._name = rabbit::String::create(_get_shared_state(_vm), _SC("main")); _fs = &funcstate; _fs->addParameter(_fs->createString(_SC("this"))); _fs->addParameter(_fs->createString(_SC("vargv"))); @@ -198,7 +198,7 @@ public: _get_shared_state(_vm)->_compilererrorhandler(_vm, _compilererror, sq_type(_sourcename) == rabbit::OT_STRING?_stringval(_sourcename):_SC("unknown"), _lex._currentline, _lex._currentcolumn); } - _vm->_lasterror = SQString::create(_get_shared_state(_vm), _compilererror, -1); + _vm->_lasterror = rabbit::String::create(_get_shared_state(_vm), _compilererror, -1); return false; } return true; @@ -305,7 +305,7 @@ public: Expect('='); rabbit::Object val = ExpectScalar(); OptionalSemicolon(); - SQTable *enums = _table(_get_shared_state(_vm)->_consts); + rabbit::Table *enums = _table(_get_shared_state(_vm)->_consts); rabbit::ObjectPtr strongid = id; enums->newSlot(strongid,rabbit::ObjectPtr(val)); strongid.Null(); @@ -1381,7 +1381,7 @@ public: _table(table)->newSlot(rabbit::ObjectPtr(key),rabbit::ObjectPtr(val)); if(_token == ',') Lex(); } - SQTable *enums = _table(_get_shared_state(_vm)->_consts); + rabbit::Table *enums = _table(_get_shared_state(_vm)->_consts); rabbit::ObjectPtr strongid = id; enums->newSlot(rabbit::ObjectPtr(strongid),rabbit::ObjectPtr(table)); strongid.Null(); diff --git a/rabbit/sqconfig.hpp b/rabbit/sqconfig.hpp index 2e0d572..be1d23d 100644 --- a/rabbit/sqconfig.hpp +++ b/rabbit/sqconfig.hpp @@ -9,10 +9,6 @@ #include -// should be the same size of a pointer -using SQHash = size_t; - - #ifdef SQUSEDOUBLE typedef double float_t; #else @@ -31,6 +27,9 @@ typedef uint64_t SQRawObjectVal; //is 32 bits on 32 bits builds and 64 bits othe #define SQ_ALIGNMENT 8 #endif +//max number of character for a printed number +#define NUMBER_MAX_CHAR 50 + namespace rabbit { using UserPointer = void*; using Bool = uint64_t; @@ -125,14 +124,11 @@ namespace rabbit { #define SQTrue (1) #define SQFalse (0) -struct SQTable; -struct SQString; struct SQClosure; struct SQGenerator; struct SQNativeClosure; struct SQFunctionProto; struct SQOuter; -struct SQSharedState; namespace rabbit { class UserData; class Array; @@ -145,4 +141,7 @@ namespace rabbit { class MemberHandle; class Instance; class Class; + class Table; + class String; + class SharedState; } \ No newline at end of file diff --git a/rabbit/sqdebug.cpp b/rabbit/sqdebug.cpp index 3f662bc..36511e1 100644 --- a/rabbit/sqdebug.cpp +++ b/rabbit/sqdebug.cpp @@ -11,7 +11,7 @@ #include #include #include -#include + #include #include @@ -70,7 +70,7 @@ void rabbit::VirtualMachine::raise_error(const rabbit::Char *s, ...) int64_t buffersize = (int64_t)scstrlen(s)+(NUMBER_MAX_CHAR*2); scvsprintf(_sp(sq_rsl(buffersize)),buffersize, s, vl); va_end(vl); - _lasterror = SQString::create(_get_shared_state(this),_spval,-1); + _lasterror = rabbit::String::create(_get_shared_state(this),_spval,-1); } void rabbit::VirtualMachine::raise_error(const rabbit::ObjectPtr &desc) @@ -78,20 +78,20 @@ void rabbit::VirtualMachine::raise_error(const rabbit::ObjectPtr &desc) _lasterror = desc; } -SQString *rabbit::VirtualMachine::printObjVal(const rabbit::ObjectPtr &o) +rabbit::String *rabbit::VirtualMachine::printObjVal(const rabbit::ObjectPtr &o) { switch(sq_type(o)) { case rabbit::OT_STRING: return _string(o); case rabbit::OT_INTEGER: scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)),sq_rsl(NUMBER_MAX_CHAR), _PRINT_INT_FMT, _integer(o)); - return SQString::create(_get_shared_state(this), _spval); + return rabbit::String::create(_get_shared_state(this), _spval); break; case rabbit::OT_FLOAT: scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)), sq_rsl(NUMBER_MAX_CHAR), _SC("%.14g"), _float(o)); - return SQString::create(_get_shared_state(this), _spval); + return rabbit::String::create(_get_shared_state(this), _spval); break; default: - return SQString::create(_get_shared_state(this), getTypeName(o)); + return rabbit::String::create(_get_shared_state(this), getTypeName(o)); } } @@ -110,15 +110,15 @@ void rabbit::VirtualMachine::raise_Compareerror(const rabbit::Object &o1, const void rabbit::VirtualMachine::raise_ParamTypeerror(int64_t nparam,int64_t typemask,int64_t type) { - rabbit::ObjectPtr exptypes = SQString::create(_get_shared_state(this), _SC(""), -1); + rabbit::ObjectPtr exptypes = rabbit::String::create(_get_shared_state(this), _SC(""), -1); int64_t found = 0; for(int64_t i=0; i<16; i++) { int64_t mask = ((int64_t)1) << i; if(typemask & (mask)) { - if(found>0) stringCat(exptypes,SQString::create(_get_shared_state(this), _SC("|"), -1), exptypes); + if(found>0) stringCat(exptypes,rabbit::String::create(_get_shared_state(this), _SC("|"), -1), exptypes); found ++; - stringCat(exptypes,SQString::create(_get_shared_state(this), IdType2Name((rabbit::ObjectType)mask), -1), exptypes); + stringCat(exptypes,rabbit::String::create(_get_shared_state(this), IdType2Name((rabbit::ObjectType)mask), -1), exptypes); } } raise_error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((rabbit::ObjectType)type), _stringval(exptypes)); diff --git a/rabbit/sqfuncproto.hpp b/rabbit/sqfuncproto.hpp index c47e7e8..aa5a358 100644 --- a/rabbit/sqfuncproto.hpp +++ b/rabbit/sqfuncproto.hpp @@ -67,11 +67,11 @@ typedef etk::Vector SQLineInfoVec; struct SQFunctionProto : public rabbit::RefCounted { private: - SQFunctionProto(SQSharedState *ss); + SQFunctionProto(rabbit::SharedState *ss); ~SQFunctionProto(); public: - static SQFunctionProto *create(SQSharedState *ss,int64_t ninstructions, + static SQFunctionProto *create(rabbit::SharedState *ss,int64_t ninstructions, int64_t nliterals,int64_t nparameters, int64_t nfunctions,int64_t noutervalues, int64_t nlineinfos,int64_t nlocalvarinfos,int64_t ndefaultparams) diff --git a/rabbit/sqfuncstate.cpp b/rabbit/sqfuncstate.cpp index 037a073..2911dfe 100644 --- a/rabbit/sqfuncstate.cpp +++ b/rabbit/sqfuncstate.cpp @@ -9,9 +9,9 @@ #include #ifndef NO_COMPILER #include -#include + #include -#include + #include #include @@ -91,11 +91,11 @@ void dumpLiteral(rabbit::ObjectPtr &o) } } -SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,compilererrorFunc efunc,void *ed) +SQFuncState::SQFuncState(rabbit::SharedState *ss,SQFuncState *parent,compilererrorFunc efunc,void *ed) { _nliterals = 0; - _literals = SQTable::create(ss,0); - _strings = SQTable::create(ss,0); + _literals = rabbit::Table::create(ss,0); + _strings = rabbit::Table::create(ss,0); _sharedstate = ss; _lastline = 0; _optimization = true; @@ -586,14 +586,14 @@ void SQFuncState::addInstruction(SQInstruction &i) rabbit::Object SQFuncState::createString(const rabbit::Char *s,int64_t len) { - rabbit::ObjectPtr ns(SQString::create(_sharedstate,s,len)); + rabbit::ObjectPtr ns(rabbit::String::create(_sharedstate,s,len)); _table(_strings)->newSlot(ns,(int64_t)1); return ns; } rabbit::Object SQFuncState::createTable() { - rabbit::ObjectPtr nt(SQTable::create(_sharedstate,0)); + rabbit::ObjectPtr nt(rabbit::Table::create(_sharedstate,0)); _table(_strings)->newSlot(nt,(int64_t)1); return nt; } @@ -632,7 +632,7 @@ SQFunctionProto *SQFuncState::buildProto() return f; } -SQFuncState *SQFuncState::pushChildState(SQSharedState *ss) +SQFuncState *SQFuncState::pushChildState(rabbit::SharedState *ss) { SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState)); new (child) SQFuncState(ss,this,_errfunc,_errtarget); diff --git a/rabbit/sqfuncstate.hpp b/rabbit/sqfuncstate.hpp index 4c532fd..d83b28a 100644 --- a/rabbit/sqfuncstate.hpp +++ b/rabbit/sqfuncstate.hpp @@ -11,13 +11,13 @@ struct SQFuncState { - SQFuncState(SQSharedState *ss,SQFuncState *parent,compilererrorFunc efunc,void *ed); + SQFuncState(rabbit::SharedState *ss,SQFuncState *parent,compilererrorFunc efunc,void *ed); ~SQFuncState(); #ifdef _DEBUG_DUMP void dump(SQFunctionProto *func); #endif void error(const rabbit::Char *err); - SQFuncState *pushChildState(SQSharedState *ss); + SQFuncState *pushChildState(rabbit::SharedState *ss); void popChildState(); void addInstruction(SQOpcode _op,int64_t arg0=0,int64_t arg1=0,int64_t arg2=0,int64_t arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);addInstruction(i);} void addInstruction(SQInstruction &i); @@ -82,13 +82,13 @@ struct SQFuncState int64_t _traps; //contains number of nested exception traps int64_t _outers; bool _optimization; - SQSharedState *_sharedstate; + rabbit::SharedState *_sharedstate; etk::Vector _childstates; int64_t getConstant(const rabbit::Object &cons); private: compilererrorFunc _errfunc; void *_errtarget; - SQSharedState *_ss; + rabbit::SharedState *_ss; }; diff --git a/rabbit/sqlexer.cpp b/rabbit/sqlexer.cpp index 22e307d..e322c2b 100644 --- a/rabbit/sqlexer.cpp +++ b/rabbit/sqlexer.cpp @@ -9,8 +9,8 @@ #include #include #include -#include -#include + + #include #include @@ -21,7 +21,7 @@ #define INIT_TEMP_STRING() { _longstr.resize(0);} #define APPEND_CHAR(c) { _longstr.pushBack(c);} #define TERMINATE_BUFFER() {_longstr.pushBack(_SC('\0'));} -#define ADD_KEYWORD(key,id) _keywords->newSlot( SQString::create(ss, _SC(#key)) ,int64_t(id)) +#define ADD_KEYWORD(key,id) _keywords->newSlot( rabbit::String::create(ss, _SC(#key)) ,int64_t(id)) SQLexer::SQLexer(){} SQLexer::~SQLexer() @@ -29,12 +29,12 @@ SQLexer::~SQLexer() _keywords->release(); } -void SQLexer::init(SQSharedState *ss, SQLEXREADFUNC rg, rabbit::UserPointer up,compilererrorFunc efunc,void *ed) +void SQLexer::init(rabbit::SharedState *ss, SQLEXREADFUNC rg, rabbit::UserPointer up,compilererrorFunc efunc,void *ed) { _errfunc = efunc; _errtarget = ed; _sharedstate = ss; - _keywords = SQTable::create(ss, 37); + _keywords = rabbit::Table::create(ss, 37); ADD_KEYWORD(while, TK_WHILE); ADD_KEYWORD(do, TK_DO); ADD_KEYWORD(if, TK_IF); diff --git a/rabbit/sqlexer.hpp b/rabbit/sqlexer.hpp index 0a31f24..34dd46b 100644 --- a/rabbit/sqlexer.hpp +++ b/rabbit/sqlexer.hpp @@ -17,7 +17,7 @@ struct SQLexer { SQLexer(); ~SQLexer(); - void init(SQSharedState *ss,SQLEXREADFUNC rg,rabbit::UserPointer up,compilererrorFunc efunc,void *ed); + void init(rabbit::SharedState *ss,SQLEXREADFUNC rg,rabbit::UserPointer up,compilererrorFunc efunc,void *ed); void error(const rabbit::Char *err); int64_t Lex(); const rabbit::Char *tok2Str(int64_t tok); @@ -38,7 +38,7 @@ private: #endif int64_t processStringHexEscape(rabbit::Char *dest, int64_t maxdigits); int64_t _curtoken; - SQTable *_keywords; + rabbit::Table *_keywords; rabbit::Bool _reached_eof; public: int64_t _prevtoken; @@ -51,7 +51,7 @@ public: SQLEXREADFUNC _readf; rabbit::UserPointer _up; LexChar _currdata; - SQSharedState *_sharedstate; + rabbit::SharedState *_sharedstate; etk::Vector _longstr; compilererrorFunc _errfunc; void *_errtarget; diff --git a/rabbit/sqobject.cpp b/rabbit/sqobject.cpp index 2717dd1..2079065 100644 --- a/rabbit/sqobject.cpp +++ b/rabbit/sqobject.cpp @@ -7,39 +7,14 @@ */ #include #include -#include + #include -#include + #include #include #include -SQString *SQString::create(SQSharedState *ss,const rabbit::Char *s,int64_t len) -{ - SQString *str=ADD_STRING(ss,s,len); - return str; -} - -void SQString::release() -{ - REMOVE_STRING(_sharedstate,this); -} - -int64_t SQString::next(const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey, rabbit::ObjectPtr &outval) -{ - int64_t idx = (int64_t)translateIndex(refpos); - while(idx < _len){ - outkey = (int64_t)idx; - outval = (int64_t)((uint64_t)_val[idx]); - //return idx for the next iteration - return ++idx; - } - //nothing to iterate anymore - return -1; -} - - bool SQGenerator::yield(rabbit::VirtualMachine *v,int64_t target) { if(_state==eSuspended) { v->raise_error(_SC("internal vm error, yielding dead generator")); return false;} @@ -251,7 +226,7 @@ bool ReadObject(rabbit::VirtualMachine* v,rabbit::UserPointer up,SQREADFUNC read int64_t len; _CHECK_IO(SafeRead(v,read,up,&len,sizeof(int64_t))); _CHECK_IO(SafeRead(v,read,up,_get_shared_state(v)->getScratchPad(sq_rsl(len)),sq_rsl(len))); - o=SQString::create(_get_shared_state(v),_get_shared_state(v)->getScratchPad(-1),len); + o=rabbit::String::create(_get_shared_state(v),_get_shared_state(v)->getScratchPad(-1),len); } break; case rabbit::OT_INTEGER:{ @@ -301,7 +276,7 @@ bool SQClosure::load(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQREADFUNC return true; } -SQFunctionProto::SQFunctionProto(SQSharedState *ss) +SQFunctionProto::SQFunctionProto(rabbit::SharedState *ss) { _stacksize=0; _bgenerator=false; diff --git a/rabbit/sqobject.hpp b/rabbit/sqobject.hpp index 35206c9..21ca789 100644 --- a/rabbit/sqobject.hpp +++ b/rabbit/sqobject.hpp @@ -21,8 +21,6 @@ #define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T')) #define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L')) -struct SQSharedState; - #define _CONSTRUCT_VECTOR(type, size, ptr) { \ for(int64_t n = 0; n < ((int64_t)size); n++) { \ new (&ptr[n]) type(); \ @@ -46,14 +44,3 @@ struct SQSharedState; vec[_n_].Null(); \ } \ } - - -inline void _Swap(rabbit::Object &a,rabbit::Object &b) -{ - rabbit::ObjectType tOldType = a._type; - rabbit::ObjectValue unOldVal = a._unVal; - a._type = b._type; - a._unVal = b._unVal; - b._type = tOldType; - b._unVal = unOldVal; -} \ No newline at end of file diff --git a/rabbit/sqpcheader.hpp b/rabbit/sqpcheader.hpp index 4feadc7..4ab3e6b 100644 --- a/rabbit/sqpcheader.hpp +++ b/rabbit/sqpcheader.hpp @@ -20,5 +20,5 @@ //rabbit stuff #include #include -#include + diff --git a/rabbit/sqstate.cpp b/rabbit/sqstate.cpp deleted file mode 100644 index f93456b..0000000 --- a/rabbit/sqstate.cpp +++ /dev/null @@ -1,468 +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) - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -SQSharedState::SQSharedState() -{ - _compilererrorhandler = NULL; - _printfunc = NULL; - _errorfunc = NULL; - _debuginfo = false; - _notifyallexceptions = false; - _foreignptr = NULL; - _releasehook = NULL; -} - -#define newsysstring(s) { \ - _systemstrings->pushBack(SQString::create(this,s)); \ - } - -#define newmetamethod(s) { \ - _metamethods->pushBack(SQString::create(this,s)); \ - _table(_metamethodsmap)->newSlot(_metamethods->back(),(int64_t)(_metamethods->size()-1)); \ - } - -bool compileTypemask(etk::Vector &res,const rabbit::Char *typemask) -{ - int64_t i = 0; - int64_t mask = 0; - while(typemask[i] != 0) { - switch(typemask[i]) { - case 'o': mask |= _RT_NULL; break; - case 'i': mask |= _RT_INTEGER; break; - case 'f': mask |= _RT_FLOAT; break; - case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break; - case 's': mask |= _RT_STRING; break; - case 't': mask |= _RT_TABLE; break; - case 'a': mask |= _RT_ARRAY; break; - case 'u': mask |= _RT_USERDATA; break; - case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break; - case 'b': mask |= _RT_BOOL; break; - case 'g': mask |= _RT_GENERATOR; break; - case 'p': mask |= _RT_USERPOINTER; break; - case 'v': mask |= _RT_THREAD; break; - case 'x': mask |= _RT_INSTANCE; break; - case 'y': mask |= _RT_CLASS; break; - case 'r': mask |= _RT_WEAKREF; break; - case '.': mask = -1; res.pushBack(mask); i++; mask = 0; continue; - case ' ': i++; continue; //ignores spaces - default: - return false; - } - i++; - if(typemask[i] == '|') { - i++; - if(typemask[i] == 0) - return false; - continue; - } - res.pushBack(mask); - mask = 0; - - } - return true; -} - -SQTable *createDefaultDelegate(SQSharedState *ss,const rabbit::RegFunction *funcz) -{ - int64_t i=0; - SQTable *t=SQTable::create(ss,0); - while(funcz[i].name!=0){ - SQNativeClosure *nc = SQNativeClosure::create(ss,funcz[i].f,0); - nc->_nparamscheck = funcz[i].nparamscheck; - nc->_name = SQString::create(ss,funcz[i].name); - if(funcz[i].typemask && !compileTypemask(nc->_typecheck,funcz[i].typemask)) - return NULL; - t->newSlot(SQString::create(ss,funcz[i].name),nc); - i++; - } - return t; -} - -void SQSharedState::init() -{ - _scratchpad=NULL; - _scratchpadsize=0; - _stringtable = (SQStringTable*)SQ_MALLOC(sizeof(SQStringTable)); - new (_stringtable) SQStringTable(this); - sq_new(_metamethods,etk::Vector); - sq_new(_systemstrings,etk::Vector); - sq_new(_types,etk::Vector); - _metamethodsmap = SQTable::create(this,rabbit::MT_LAST-1); - //adding type strings to avoid memory trashing - //types names - newsysstring(_SC("null")); - newsysstring(_SC("table")); - newsysstring(_SC("array")); - newsysstring(_SC("closure")); - newsysstring(_SC("string")); - newsysstring(_SC("userdata")); - newsysstring(_SC("integer")); - newsysstring(_SC("float")); - newsysstring(_SC("userpointer")); - newsysstring(_SC("function")); - newsysstring(_SC("generator")); - newsysstring(_SC("thread")); - newsysstring(_SC("class")); - newsysstring(_SC("instance")); - newsysstring(_SC("bool")); - //meta methods - newmetamethod(MM_ADD); - newmetamethod(MM_SUB); - newmetamethod(MM_MUL); - newmetamethod(MM_DIV); - newmetamethod(MM_UNM); - newmetamethod(MM_MODULO); - newmetamethod(MM_SET); - newmetamethod(MM_GET); - newmetamethod(MM_TYPEOF); - newmetamethod(MM_NEXTI); - newmetamethod(MM_CMP); - newmetamethod(MM_CALL); - newmetamethod(MM_CLONED); - newmetamethod(MM_NEWSLOT); - newmetamethod(MM_DELSLOT); - newmetamethod(MM_TOSTRING); - newmetamethod(MM_NEWMEMBER); - newmetamethod(MM_INHERITED); - - _constructoridx = SQString::create(this,_SC("constructor")); - _registry = SQTable::create(this,0); - _consts = SQTable::create(this,0); - _table_default_delegate = createDefaultDelegate(this,_table_default_delegate_funcz); - _array_default_delegate = createDefaultDelegate(this,_array_default_delegate_funcz); - _string_default_delegate = createDefaultDelegate(this,_string_default_delegate_funcz); - _number_default_delegate = createDefaultDelegate(this,_number_default_delegate_funcz); - _closure_default_delegate = createDefaultDelegate(this,_closure_default_delegate_funcz); - _generator_default_delegate = createDefaultDelegate(this,_generator_default_delegate_funcz); - _thread_default_delegate = createDefaultDelegate(this,_thread_default_delegate_funcz); - _class_default_delegate = createDefaultDelegate(this,_class_default_delegate_funcz); - _instance_default_delegate = createDefaultDelegate(this,_instance_default_delegate_funcz); - _weakref_default_delegate = createDefaultDelegate(this,_weakref_default_delegate_funcz); -} - -SQSharedState::~SQSharedState() -{ - if(_releasehook) { _releasehook(_foreignptr,0); _releasehook = NULL; } - _constructoridx.Null(); - _table(_registry)->finalize(); - _table(_consts)->finalize(); - _table(_metamethodsmap)->finalize(); - _registry.Null(); - _consts.Null(); - _metamethodsmap.Null(); - while(!_systemstrings->empty()) { - _systemstrings->back().Null(); - _systemstrings->popBack(); - } - _thread(_root_vm)->finalize(); - _root_vm.Null(); - _table_default_delegate.Null(); - _array_default_delegate.Null(); - _string_default_delegate.Null(); - _number_default_delegate.Null(); - _closure_default_delegate.Null(); - _generator_default_delegate.Null(); - _thread_default_delegate.Null(); - _class_default_delegate.Null(); - _instance_default_delegate.Null(); - _weakref_default_delegate.Null(); - _refs_table.finalize(); - - using tmpType = etk::Vector; - sq_delete(_types, tmpType); - sq_delete(_systemstrings, tmpType); - sq_delete(_metamethods, tmpType); - sq_delete(_stringtable, SQStringTable); - if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize); -} - - -int64_t SQSharedState::getMetaMethodIdxByName(const rabbit::ObjectPtr &name) -{ - if(sq_type(name) != rabbit::OT_STRING) - return -1; - rabbit::ObjectPtr ret; - if(_table(_metamethodsmap)->get(name,ret)) { - return _integer(ret); - } - return -1; -} - - -rabbit::Char* SQSharedState::getScratchPad(int64_t size) -{ - int64_t newsize; - if(size>0) { - if(_scratchpadsize < size) { - newsize = size + (size>>1); - _scratchpad = (rabbit::Char *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); - _scratchpadsize = newsize; - - }else if(_scratchpadsize >= (size<<5)) { - newsize = _scratchpadsize >> 1; - _scratchpad = (rabbit::Char *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); - _scratchpadsize = newsize; - } - } - return _scratchpad; -} - -RefTable::RefTable() -{ - allocNodes(4); -} - -void RefTable::finalize() -{ - RefNode *nodes = _nodes; - for(uint64_t n = 0; n < _numofslots; n++) { - nodes->obj.Null(); - nodes++; - } -} - -RefTable::~RefTable() -{ - SQ_FREE(_buckets,(_numofslots * sizeof(RefNode *)) + (_numofslots * sizeof(RefNode))); -} - - -void RefTable::addRef(rabbit::Object &obj) -{ - SQHash mainpos; - RefNode *prev; - RefNode *ref = get(obj,mainpos,&prev,true); - ref->refs++; -} - -uint64_t RefTable::getRefCount(rabbit::Object &obj) -{ - SQHash mainpos; - RefNode *prev; - RefNode *ref = get(obj,mainpos,&prev,true); - return ref->refs; -} - - -rabbit::Bool RefTable::release(rabbit::Object &obj) -{ - SQHash mainpos; - RefNode *prev; - RefNode *ref = get(obj,mainpos,&prev,false); - if(ref) { - if(--ref->refs == 0) { - rabbit::ObjectPtr o = ref->obj; - if(prev) { - prev->next = ref->next; - } - else { - _buckets[mainpos] = ref->next; - } - ref->next = _freelist; - _freelist = ref; - _slotused--; - ref->obj.Null(); - //<>test for shrink? - return SQTrue; - } - } - else { - assert(0); - } - return SQFalse; -} - -void RefTable::resize(uint64_t size) -{ - RefNode **oldbucks = _buckets; - RefNode *t = _nodes; - uint64_t oldnumofslots = _numofslots; - allocNodes(size); - //rehash - uint64_t nfound = 0; - for(uint64_t n = 0; n < oldnumofslots; n++) { - if(sq_type(t->obj) != rabbit::OT_NULL) { - //add back; - assert(t->refs != 0); - RefNode *nn = add(::HashObj(t->obj)&(_numofslots-1),t->obj); - nn->refs = t->refs; - t->obj.Null(); - nfound++; - } - t++; - } - assert(nfound == oldnumofslots); - SQ_FREE(oldbucks,(oldnumofslots * sizeof(RefNode *)) + (oldnumofslots * sizeof(RefNode))); -} - -RefTable::RefNode *RefTable::add(SQHash mainpos,rabbit::Object &obj) -{ - RefNode *t = _buckets[mainpos]; - RefNode *newnode = _freelist; - newnode->obj = obj; - _buckets[mainpos] = newnode; - _freelist = _freelist->next; - newnode->next = t; - assert(newnode->refs == 0); - _slotused++; - return newnode; -} - -RefTable::RefNode *RefTable::get(rabbit::Object &obj,SQHash &mainpos,RefNode **prev,bool addIfNeeded) -{ - RefNode *ref; - mainpos = ::HashObj(obj)&(_numofslots-1); - *prev = NULL; - for (ref = _buckets[mainpos]; ref; ) { - if(_rawval(ref->obj) == _rawval(obj) && sq_type(ref->obj) == sq_type(obj)) - break; - *prev = ref; - ref = ref->next; - } - if(ref == NULL && addIfNeeded) { - if(_numofslots == _slotused) { - assert(_freelist == 0); - resize(_numofslots*2); - mainpos = ::HashObj(obj)&(_numofslots-1); - } - ref = add(mainpos,obj); - } - return ref; -} - -void RefTable::allocNodes(uint64_t size) -{ - RefNode **bucks; - RefNode *nodes; - bucks = (RefNode **)SQ_MALLOC((size * sizeof(RefNode *)) + (size * sizeof(RefNode))); - nodes = (RefNode *)&bucks[size]; - RefNode *temp = nodes; - uint64_t n; - for(n = 0; n < size - 1; n++) { - bucks[n] = NULL; - temp->refs = 0; - new (&temp->obj) rabbit::ObjectPtr; - temp->next = temp+1; - temp++; - } - bucks[n] = NULL; - temp->refs = 0; - new (&temp->obj) rabbit::ObjectPtr; - temp->next = NULL; - _freelist = nodes; - _nodes = nodes; - _buckets = bucks; - _slotused = 0; - _numofslots = size; -} -////////////////////////////////////////////////////////////////////////// -//SQStringTable -/* -* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.) -* http://www.lua.org/copyright.html#4 -* http://www.lua.org/source/4.0.1/src_lstring.c.html -*/ - -SQStringTable::SQStringTable(SQSharedState *ss) -{ - _sharedstate = ss; - allocNodes(4); - _slotused = 0; -} - -SQStringTable::~SQStringTable() -{ - SQ_FREE(_strings,sizeof(SQString*)*_numofslots); - _strings = NULL; -} - -void SQStringTable::allocNodes(int64_t size) -{ - _numofslots = size; - _strings = (SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots); - memset(_strings,0,sizeof(SQString*)*_numofslots); -} - -SQString *SQStringTable::add(const rabbit::Char *news,int64_t len) -{ - if(len<0) - len = (int64_t)scstrlen(news); - SQHash newhash = ::_hashstr(news,len); - SQHash h = newhash&(_numofslots-1); - SQString *s; - for (s = _strings[h]; s; s = s->_next){ - if(s->_len == len && (!memcmp(news,s->_val,sq_rsl(len)))) - return s; //found - } - - SQString *t = (SQString *)SQ_MALLOC(sq_rsl(len)+sizeof(SQString)); - new (t) SQString; - t->_sharedstate = _sharedstate; - memcpy(t->_val,news,sq_rsl(len)); - t->_val[len] = _SC('\0'); - t->_len = len; - t->_hash = newhash; - t->_next = _strings[h]; - _strings[h] = t; - _slotused++; - if (_slotused > _numofslots) /* too crowded? */ - resize(_numofslots*2); - return t; -} - -void SQStringTable::resize(int64_t size) -{ - int64_t oldsize=_numofslots; - SQString **oldtable=_strings; - allocNodes(size); - for (int64_t i=0; i_next; - SQHash h = p->_hash&(_numofslots-1); - p->_next = _strings[h]; - _strings[h] = p; - p = next; - } - } - SQ_FREE(oldtable,oldsize*sizeof(SQString*)); -} - -void SQStringTable::remove(SQString *bs) -{ - SQString *s; - SQString *prev=NULL; - SQHash h = bs->_hash&(_numofslots - 1); - - for (s = _strings[h]; s; ){ - if(s == bs){ - if(prev) - prev->_next = s->_next; - else - _strings[h] = s->_next; - _slotused--; - int64_t slen = s->_len; - s->~SQString(); - SQ_FREE(s,sizeof(SQString) + sq_rsl(slen)); - return; - } - prev = s; - s = s->_next; - } - assert(0);//if this fail something is wrong -} diff --git a/rabbit/sqstate.hpp b/rabbit/sqstate.hpp deleted file mode 100644 index 63b1521..0000000 --- a/rabbit/sqstate.hpp +++ /dev/null @@ -1,131 +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 - -#include -#include -#include -#include - -struct SQString; -struct SQTable; -//max number of character for a printed number -#define NUMBER_MAX_CHAR 50 - -struct SQStringTable -{ - SQStringTable(SQSharedState*ss); - ~SQStringTable(); - SQString *add(const rabbit::Char *,int64_t len); - void remove(SQString *); -private: - void resize(int64_t size); - void allocNodes(int64_t size); - SQString **_strings; - uint64_t _numofslots; - uint64_t _slotused; - SQSharedState *_sharedstate; -}; - -struct RefTable { - struct RefNode { - rabbit::ObjectPtr obj; - uint64_t refs; - struct RefNode *next; - }; - RefTable(); - ~RefTable(); - void addRef(rabbit::Object &obj); - rabbit::Bool release(rabbit::Object &obj); - uint64_t getRefCount(rabbit::Object &obj); - void finalize(); -private: - RefNode *get(rabbit::Object &obj,SQHash &mainpos,RefNode **prev,bool add); - RefNode *add(SQHash mainpos,rabbit::Object &obj); - void resize(uint64_t size); - void allocNodes(uint64_t size); - uint64_t _numofslots; - uint64_t _slotused; - RefNode *_nodes; - RefNode *_freelist; - RefNode **_buckets; -}; - -#define ADD_STRING(ss,str,len) ss->_stringtable->add(str,len) -#define REMOVE_STRING(ss,bstr) ss->_stringtable->remove(bstr) -namespace rabbit { - class ObjectPtr; -} -struct SQSharedState -{ - SQSharedState(); - ~SQSharedState(); - void init(); -public: - rabbit::Char* getScratchPad(int64_t size); - int64_t getMetaMethodIdxByName(const rabbit::ObjectPtr &name); - etk::Vector *_metamethods; - rabbit::ObjectPtr _metamethodsmap; - etk::Vector *_systemstrings; - etk::Vector *_types; - SQStringTable *_stringtable; - RefTable _refs_table; - rabbit::ObjectPtr _registry; - rabbit::ObjectPtr _consts; - rabbit::ObjectPtr _constructoridx; - rabbit::ObjectPtr _root_vm; - rabbit::ObjectPtr _table_default_delegate; - static const rabbit::RegFunction _table_default_delegate_funcz[]; - rabbit::ObjectPtr _array_default_delegate; - static const rabbit::RegFunction _array_default_delegate_funcz[]; - rabbit::ObjectPtr _string_default_delegate; - static const rabbit::RegFunction _string_default_delegate_funcz[]; - rabbit::ObjectPtr _number_default_delegate; - static const rabbit::RegFunction _number_default_delegate_funcz[]; - rabbit::ObjectPtr _generator_default_delegate; - static const rabbit::RegFunction _generator_default_delegate_funcz[]; - rabbit::ObjectPtr _closure_default_delegate; - static const rabbit::RegFunction _closure_default_delegate_funcz[]; - rabbit::ObjectPtr _thread_default_delegate; - static const rabbit::RegFunction _thread_default_delegate_funcz[]; - rabbit::ObjectPtr _class_default_delegate; - static const rabbit::RegFunction _class_default_delegate_funcz[]; - rabbit::ObjectPtr _instance_default_delegate; - static const rabbit::RegFunction _instance_default_delegate_funcz[]; - rabbit::ObjectPtr _weakref_default_delegate; - static const rabbit::RegFunction _weakref_default_delegate_funcz[]; - - SQCOMPILERERROR _compilererrorhandler; - SQPRINTFUNCTION _printfunc; - SQPRINTFUNCTION _errorfunc; - bool _debuginfo; - bool _notifyallexceptions; - rabbit::UserPointer _foreignptr; - SQRELEASEHOOK _releasehook; -private: - rabbit::Char *_scratchpad; - int64_t _scratchpadsize; -}; - -#define _sp(s) (_sharedstate->getScratchPad(s)) -#define _spval (_sharedstate->getScratchPad(-1)) - -#define _table_ddel _table(_sharedstate->_table_default_delegate) -#define _array_ddel _table(_sharedstate->_array_default_delegate) -#define _string_ddel _table(_sharedstate->_string_default_delegate) -#define _number_ddel _table(_sharedstate->_number_default_delegate) -#define _generator_ddel _table(_sharedstate->_generator_default_delegate) -#define _closure_ddel _table(_sharedstate->_closure_default_delegate) -#define _thread_ddel _table(_sharedstate->_thread_default_delegate) -#define _class_ddel _table(_sharedstate->_class_default_delegate) -#define _instance_ddel _table(_sharedstate->_instance_default_delegate) -#define _weakref_ddel _table(_sharedstate->_weakref_default_delegate) - -bool compileTypemask(etk::Vector &res,const rabbit::Char *typemask); - - diff --git a/rabbit/sqstring.hpp b/rabbit/sqstring.hpp deleted file mode 100644 index c0baaf2..0000000 --- a/rabbit/sqstring.hpp +++ /dev/null @@ -1,35 +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 - -inline SQHash _hashstr (const rabbit::Char *s, size_t l) -{ - SQHash h = (SQHash)l; /* seed */ - size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */ - for (; l>=step; l-=step) - h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++)); - return h; -} - -struct SQString : public rabbit::RefCounted -{ - SQString(){} - ~SQString(){} -public: - static SQString *create(SQSharedState *ss, const rabbit::Char *, int64_t len = -1 ); - int64_t next(const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey, rabbit::ObjectPtr &outval); - void release(); - SQSharedState *_sharedstate; - SQString *_next; //chain for the string table - int64_t _len; - SQHash _hash; - rabbit::Char _val[1]; -}; - - - diff --git a/rabbit/sqtable.hpp b/rabbit/sqtable.hpp deleted file mode 100644 index 5235d56..0000000 --- a/rabbit/sqtable.hpp +++ /dev/null @@ -1,120 +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 - -/* -* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.) -* http://www.lua.org/copyright.html#4 -* http://www.lua.org/source/4.0.1/src_ltable.c.html -*/ - -#include -#include -#include -#include -#include -#include - - -#define hashptr(p) ((SQHash)(((int64_t)p) >> 3)) - -inline SQHash HashObj(const rabbit::ObjectPtr &key) -{ - switch(sq_type(key)) { - case rabbit::OT_STRING: - return _string(key)->_hash; - case rabbit::OT_FLOAT: - return (SQHash)((int64_t)_float(key)); - case rabbit::OT_BOOL: - case rabbit::OT_INTEGER: - return (SQHash)((int64_t)_integer(key)); - default: - return hashptr(key._unVal.pRefCounted); - } -} - -struct SQTable : public rabbit::Delegable -{ -private: - struct _HashNode - { - _HashNode() { next = NULL; } - rabbit::ObjectPtr val; - rabbit::ObjectPtr key; - _HashNode *next; - }; - _HashNode *_firstfree; - _HashNode *_nodes; - int64_t _numofnodes; - int64_t _usednodes; - -/////////////////////////// - void allocNodes(int64_t nsize); - void Rehash(bool force); - SQTable(SQSharedState *ss, int64_t ninitialsize); - void _clearNodes(); -public: - static SQTable* create(SQSharedState *ss,int64_t ninitialsize) - { - char* tmp = (char*)SQ_MALLOC(sizeof(SQTable)); - SQTable *newtable = new (tmp) SQTable(ss, ninitialsize); - newtable->_delegate = NULL; - return newtable; - } - void finalize(); - SQTable *clone(); - ~SQTable() - { - setDelegate(NULL); - for (int64_t i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode(); - SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode)); - } - inline _HashNode *_get(const rabbit::ObjectPtr &key,SQHash hash) - { - _HashNode *n = &_nodes[hash]; - do{ - if(_rawval(n->key) == _rawval(key) && sq_type(n->key) == sq_type(key)){ - return n; - } - }while((n = n->next)); - return NULL; - } - //for compiler use - inline bool getStr(const rabbit::Char* key,int64_t keylen,rabbit::ObjectPtr &val) - { - SQHash hash = _hashstr(key,keylen); - _HashNode *n = &_nodes[hash & (_numofnodes - 1)]; - _HashNode *res = NULL; - do{ - if(sq_type(n->key) == rabbit::OT_STRING && (scstrcmp(_stringval(n->key),key) == 0)){ - res = n; - break; - } - }while((n = n->next)); - if (res) { - val = _realval(res->val); - return true; - } - return false; - } - bool get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val); - void remove(const rabbit::ObjectPtr &key); - bool set(const rabbit::ObjectPtr &key, const rabbit::ObjectPtr &val); - //returns true if a new slot has been created false if it was already present - bool newSlot(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val); - int64_t next(bool getweakrefs,const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey, rabbit::ObjectPtr &outval); - - int64_t countUsed(){ return _usednodes;} - void clear(); - void release() - { - sq_delete(this, SQTable); - } - -}; -