[DEV] continue rework (little bug...)

This commit is contained in:
Edouard DUPIN 2018-06-28 22:29:10 +02:00
parent 394cc68950
commit 45e2df01f0
46 changed files with 1187 additions and 1060 deletions

View File

@ -27,6 +27,12 @@ def get_version():
def configure(target, my_module): def configure(target, my_module):
my_module.add_src_file([ 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/sqmem.cpp',
'rabbit/sqbaselib.cpp', 'rabbit/sqbaselib.cpp',
'rabbit/sqapi.cpp', 'rabbit/sqapi.cpp',
@ -36,8 +42,6 @@ def configure(target, my_module):
'rabbit/Instance.cpp', 'rabbit/Instance.cpp',
'rabbit/AutoDec.cpp', 'rabbit/AutoDec.cpp',
'rabbit/VirtualMachine.cpp', 'rabbit/VirtualMachine.cpp',
'rabbit/sqtable.cpp',
'rabbit/sqstate.cpp',
'rabbit/sqobject.cpp', 'rabbit/sqobject.cpp',
'rabbit/sqcompiler.cpp', 'rabbit/sqcompiler.cpp',
'rabbit/sqdebug.cpp', 'rabbit/sqdebug.cpp',
@ -64,12 +68,17 @@ def configure(target, my_module):
'etk-base', 'etk-base',
]) ])
my_module.add_header_file([ 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/Class.hpp',
'rabbit/ClassMember.hpp', 'rabbit/ClassMember.hpp',
'rabbit/Instance.hpp', 'rabbit/Instance.hpp',
'rabbit/AutoDec.hpp', 'rabbit/AutoDec.hpp',
'rabbit/VirtualMachine.hpp', 'rabbit/VirtualMachine.hpp',
'rabbit/sqstate.hpp',
'rabbit/rabbit.hpp', 'rabbit/rabbit.hpp',
'rabbit/sqobject.hpp', 'rabbit/sqobject.hpp',
'rabbit/sqopcodes.hpp', 'rabbit/sqopcodes.hpp',
@ -83,8 +92,6 @@ def configure(target, my_module):
'rabbit/sqclosure.hpp', 'rabbit/sqclosure.hpp',
'rabbit/sqlexer.hpp', 'rabbit/sqlexer.hpp',
'rabbit/sqfuncstate.hpp', 'rabbit/sqfuncstate.hpp',
'rabbit/sqstring.hpp',
'rabbit/sqtable.hpp',
'rabbit/RefCounted.hpp', 'rabbit/RefCounted.hpp',
'rabbit/WeakRef.hpp', 'rabbit/WeakRef.hpp',
'rabbit/Delegable.hpp', 'rabbit/Delegable.hpp',

View File

@ -11,7 +11,7 @@ namespace rabbit {
class Array : public rabbit::RefCounted class Array : public rabbit::RefCounted
{ {
private: private:
Array(SQSharedState* _ss, Array(rabbit::SharedState* _ss,
int64_t _nsize) { int64_t _nsize) {
m_data.resize(_nsize); m_data.resize(_nsize);
} }
@ -20,7 +20,7 @@ namespace rabbit {
} }
public: public:
// TODO : remove this ETK_ALLOC can do it natively ... // TODO : remove this ETK_ALLOC can do it natively ...
static Array* create(SQSharedState* _ss, static Array* create(rabbit::SharedState* _ss,
int64_t _ninitialsize) { int64_t _ninitialsize) {
Array *newarray=(Array*)SQ_MALLOC(sizeof(Array)); Array *newarray=(Array*)SQ_MALLOC(sizeof(Array));
new (newarray) Array(_ss, _ninitialsize); new (newarray) Array(_ss, _ninitialsize);

View File

@ -7,9 +7,11 @@
*/ */
#include <rabbit/Class.hpp> #include <rabbit/Class.hpp>
#include <rabbit/Instance.hpp> #include <rabbit/Instance.hpp>
#include <rabbit/Table.hpp>
#include <rabbit/SharedState.hpp>
rabbit::Class::Class(SQSharedState *ss,rabbit::Class *base) { rabbit::Class::Class(rabbit::SharedState *ss, rabbit::Class *base) {
_base = base; _base = base;
_typetag = 0; _typetag = 0;
_hook = NULL; _hook = NULL;
@ -24,7 +26,7 @@ rabbit::Class::Class(SQSharedState *ss,rabbit::Class *base) {
_COPY_VECTOR(_metamethods,base->_metamethods, rabbit::MT_LAST); _COPY_VECTOR(_metamethods,base->_metamethods, rabbit::MT_LAST);
__ObjaddRef(_base); __ObjaddRef(_base);
} }
_members = base?base->_members->clone() : SQTable::create(ss,0); _members = base?base->_members->clone() : rabbit::Table::create(ss,0);
__ObjaddRef(_members); __ObjaddRef(_members);
} }
@ -43,7 +45,48 @@ rabbit::Class::~Class() {
finalize(); 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; rabbit::ObjectPtr temp;
bool belongs_to_static_table = sq_type(val) == rabbit::OT_CLOSURE bool belongs_to_static_table = sq_type(val) == rabbit::OT_CLOSURE
|| sq_type(val) == rabbit::OT_NATIVECLOSURE || sq_type(val) == rabbit::OT_NATIVECLOSURE

View File

@ -10,54 +10,29 @@
#include <etk/types.hpp> #include <etk/types.hpp>
#include <rabbit/sqpcheader.hpp> #include <rabbit/sqpcheader.hpp>
#include <rabbit/VirtualMachine.hpp> #include <rabbit/VirtualMachine.hpp>
#include <rabbit/sqtable.hpp>
#include <rabbit/sqfuncproto.hpp> #include <rabbit/sqfuncproto.hpp>
#include <rabbit/sqclosure.hpp> #include <rabbit/sqclosure.hpp>
#include <rabbit/MetaMethod.hpp>
#include <rabbit/ClassMember.hpp> #include <rabbit/ClassMember.hpp>
namespace rabbit { namespace rabbit {
class Class : public rabbit::RefCounted { class Class : public rabbit::RefCounted {
public: public:
Class(SQSharedState *ss,rabbit::Class *base); Class(rabbit::SharedState *ss,rabbit::Class *base);
public: public:
static Class* create(SQSharedState *ss, Class *base) { static Class* create(rabbit::SharedState *ss, Class *base);
rabbit::Class *newclass = (Class *)SQ_MALLOC(sizeof(Class));
new (newclass) Class(ss, base);
return newclass;
}
~Class(); ~Class();
bool newSlot(SQSharedState *ss, const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val,bool bstatic); 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 get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val);
if(_members->get(key,val)) { bool getConstructor(rabbit::ObjectPtr &ctor);
if(_isfield(val)) {
rabbit::ObjectPtr &o = _defaultvalues[_member_idx(val)].val;
val = _realval(o);
} else {
val = _methods[_member_idx(val)].val;
}
return true;
}
return false;
}
bool getConstructor(rabbit::ObjectPtr &ctor) {
if(_constructoridx != -1) {
ctor = _methods[_constructoridx].val;
return true;
}
return false;
}
bool setAttributes(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val); bool setAttributes(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val);
bool getAttributes(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &outval); bool getAttributes(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &outval);
void lock() { _locked = true; if(_base) _base->lock(); } void lock();
void release() { void release();
if (_hook) { _hook(_typetag,0);}
sq_delete(this, Class);
}
void finalize(); void finalize();
int64_t next(const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey, rabbit::ObjectPtr &outval); int64_t next(const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey, rabbit::ObjectPtr &outval);
rabbit::Instance *createInstance(); rabbit::Instance *createInstance();
SQTable *_members; rabbit::Table *_members;
rabbit::Class *_base; rabbit::Class *_base;
etk::Vector<rabbit::ClassMember> _defaultvalues; etk::Vector<rabbit::ClassMember> _defaultvalues;
etk::Vector<rabbit::ClassMember> _methods; etk::Vector<rabbit::ClassMember> _methods;
@ -71,5 +46,6 @@ namespace rabbit {
}; };
#define calcinstancesize(_theclass_) \ #define calcinstancesize(_theclass_) \
(_theclass_->_udsize + sq_aligning(sizeof(rabbit::Instance) + (sizeof(rabbit::ObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0)))) (_theclass_->_udsize + sq_aligning(sizeof(rabbit::Instance) + (sizeof(rabbit::ObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0))))
}
};

View File

@ -7,9 +7,11 @@
*/ */
#include <rabbit/Delegable.hpp> #include <rabbit/Delegable.hpp>
#include <rabbit/sqtable.hpp>
#include <rabbit/VirtualMachine.hpp> #include <rabbit/VirtualMachine.hpp>
#include <rabbit/sqstate.hpp> #include <rabbit/Table.hpp>
#include <rabbit/SharedState.hpp>
bool rabbit::Delegable::getMetaMethod(rabbit::VirtualMachine *v,rabbit::MetaMethod mm,rabbit::ObjectPtr &res) { bool rabbit::Delegable::getMetaMethod(rabbit::VirtualMachine *v,rabbit::MetaMethod mm,rabbit::ObjectPtr &res) {
if(_delegate) { if(_delegate) {
@ -18,8 +20,8 @@ bool rabbit::Delegable::getMetaMethod(rabbit::VirtualMachine *v,rabbit::MetaMeth
return false; return false;
} }
bool rabbit::Delegable::setDelegate(SQTable *mt) { bool rabbit::Delegable::setDelegate(rabbit::Table *mt) {
SQTable *temp = mt; rabbit::Table *temp = mt;
if(temp == this) { if(temp == this) {
return false; return false;
} }

View File

@ -12,14 +12,14 @@
#include <rabbit/MetaMethod.hpp> #include <rabbit/MetaMethod.hpp>
#include <rabbit/ObjectPtr.hpp> #include <rabbit/ObjectPtr.hpp>
struct SQTable;
namespace rabbit { namespace rabbit {
class Table;
class VirtualMachine; class VirtualMachine;
class Delegable : public rabbit::RefCounted { class Delegable : public rabbit::RefCounted {
public: public:
bool setDelegate(SQTable *m); bool setDelegate(rabbit::Table *m);
public: public:
virtual bool getMetaMethod(rabbit::VirtualMachine *v, rabbit::MetaMethod mm, rabbit::ObjectPtr& res); virtual bool getMetaMethod(rabbit::VirtualMachine *v, rabbit::MetaMethod mm, rabbit::ObjectPtr& res);
SQTable *_delegate; rabbit::Table *_delegate;
}; };
} }

13
rabbit/Hash.cpp Normal file
View File

@ -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 <rabbit/Hash.hpp>

17
rabbit/Hash.hpp Normal file
View File

@ -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 <etk/types.hpp>
namespace rabbit {
// should be the same size of a pointer
using Hash = size_t;
}

View File

@ -6,15 +6,17 @@
* @license MPL-2 (see license file) * @license MPL-2 (see license file)
*/ */
#include <rabbit/Instance.hpp> #include <rabbit/Instance.hpp>
#include <rabbit/Table.hpp>
#include <rabbit/SharedState.hpp>
void rabbit::Instance::init(SQSharedState *ss) { void rabbit::Instance::init(rabbit::SharedState *ss) {
_userpointer = NULL; _userpointer = NULL;
_hook = NULL; _hook = NULL;
__ObjaddRef(_class); __ObjaddRef(_class);
_delegate = _class->_members; _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; _memsize = memsize;
_class = c; _class = c;
uint64_t nvalues = _class->_defaultvalues.size(); uint64_t nvalues = _class->_defaultvalues.size();
@ -24,7 +26,7 @@ rabbit::Instance::Instance(SQSharedState *ss, rabbit::Class *c, int64_t memsize)
init(ss); 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; _memsize = memsize;
_class = i->_class; _class = i->_class;
uint64_t nvalues = _class->_defaultvalues.size(); uint64_t nvalues = _class->_defaultvalues.size();
@ -64,3 +66,60 @@ bool rabbit::Instance::instanceOf(rabbit::Class *trg) {
} }
return false; 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);
}

View File

@ -10,69 +10,26 @@
#include <etk/types.hpp> #include <etk/types.hpp>
#include <rabbit/sqpcheader.hpp> #include <rabbit/sqpcheader.hpp>
#include <rabbit/VirtualMachine.hpp> #include <rabbit/VirtualMachine.hpp>
#include <rabbit/sqtable.hpp>
#include <rabbit/sqfuncproto.hpp> #include <rabbit/sqfuncproto.hpp>
#include <rabbit/sqclosure.hpp> #include <rabbit/sqclosure.hpp>
#include <rabbit/MetaMethod.hpp> #include <rabbit/MetaMethod.hpp>
#include <rabbit/Delegable.hpp>
namespace rabbit { namespace rabbit {
class Instance : public rabbit::Delegable { class Instance : public rabbit::Delegable {
public: public:
void init(SQSharedState *ss); void init(rabbit::SharedState *ss);
Instance(SQSharedState *ss, rabbit::Class *c, int64_t memsize); Instance(rabbit::SharedState *ss, rabbit::Class *c, int64_t memsize);
Instance(SQSharedState *ss, Instance *c, int64_t memsize); Instance(rabbit::SharedState *ss, Instance *c, int64_t memsize);
public: public:
static Instance* create(SQSharedState *ss,rabbit::Class *theclass) { static Instance* create(rabbit::SharedState *ss,rabbit::Class *theclass);
int64_t size = calcinstancesize(theclass); Instance *clone(rabbit::SharedState *ss);
Instance *newinst = (Instance *)SQ_MALLOC(size);
new (newinst) Instance(ss, theclass,size);
if(theclass->_udsize) {
newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize);
}
return newinst;
}
Instance *clone(SQSharedState *ss)
{
int64_t size = calcinstancesize(_class);
Instance *newinst = (Instance *)SQ_MALLOC(size);
new (newinst) Instance(ss, this,size);
if(_class->_udsize) {
newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize);
}
return newinst;
}
~Instance(); ~Instance();
bool get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val) { bool get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val);
if(_class->_members->get(key,val)) { bool set(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val);
if(_isfield(val)) { void release();
rabbit::ObjectPtr &o = _values[_member_idx(val)];
val = _realval(o);
}
else {
val = _class->_methods[_member_idx(val)].val;
}
return true;
}
return false;
}
bool set(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val) {
rabbit::ObjectPtr idx;
if(_class->_members->get(key,idx) && _isfield(idx)) {
_values[_member_idx(idx)] = val;
return true;
}
return false;
}
void release() {
_uiRef++;
if (_hook) { _hook(_userpointer,0);}
_uiRef--;
if(_uiRef > 0) return;
int64_t size = _memsize;
this->~Instance();
SQ_FREE(this, size);
}
void finalize(); void finalize();
bool instanceOf(rabbit::Class *trg); bool instanceOf(rabbit::Class *trg);
bool getMetaMethod(rabbit::VirtualMachine *v,rabbit::MetaMethod mm,rabbit::ObjectPtr &res); bool getMetaMethod(rabbit::VirtualMachine *v,rabbit::MetaMethod mm,rabbit::ObjectPtr &res);

View File

@ -81,4 +81,13 @@ namespace rabbit {
#define sq_isweakref(o) ((o)._type==rabbit::OT_WEAKREF) #define sq_isweakref(o) ((o)._type==rabbit::OT_WEAKREF)
#define sq_type(o) ((o)._type) #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;
}
} }

View File

@ -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_CLASS, rabbit::Class, pClass)
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_INSTANCE, rabbit::Instance, pInstance) RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_INSTANCE, rabbit::Instance, pInstance)
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_ARRAY, rabbit::Array, pArray) RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_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_NATIVECLOSURE, SQNativeClosure, pNativeClosure)
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_OUTER, SQOuter, pOuter) 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_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_USERDATA, rabbit::UserData, pUserData)
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_WEAKREF, rabbit::WeakRef, pWeakRef) RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_WEAKREF, rabbit::WeakRef, pWeakRef)
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_THREAD, rabbit::VirtualMachine, pThread) RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_THREAD, rabbit::VirtualMachine, pThread)

View File

@ -33,7 +33,7 @@ namespace rabbit {
ObjectPtr(const ObjectPtr& _obj); ObjectPtr(const ObjectPtr& _obj);
ObjectPtr(const Object& _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_CLASS, rabbit::Class, pClass)
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_INSTANCE, rabbit::Instance, pInstance) RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_INSTANCE, rabbit::Instance, pInstance)
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_ARRAY, rabbit::Array, pArray) RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_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_NATIVECLOSURE, SQNativeClosure, pNativeClosure)
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_OUTER, SQOuter, pOuter) 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_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_USERDATA, UserData, pUserData)
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_WEAKREF, WeakRef, pWeakRef) RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_WEAKREF, WeakRef, pWeakRef)
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_THREAD, VirtualMachine, pThread) RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_THREAD, VirtualMachine, pThread)

View File

@ -12,18 +12,17 @@
namespace rabbit { namespace rabbit {
union ObjectValue union ObjectValue {
{
struct SQTable *pTable;
struct SQClosure *pClosure; struct SQClosure *pClosure;
struct SQOuter *pOuter; struct SQOuter *pOuter;
struct SQGenerator *pGenerator; struct SQGenerator *pGenerator;
struct SQNativeClosure *pNativeClosure; struct SQNativeClosure *pNativeClosure;
struct SQString *pString;
int64_t nInteger; int64_t nInteger;
float_t fFloat; float_t fFloat;
struct SQFunctionProto *pFunctionProto; struct SQFunctionProto *pFunctionProto;
rabbit::Table* pTable;
rabbit::String* pString;
rabbit::Class* pClass; rabbit::Class* pClass;
rabbit::Instance* pInstance; rabbit::Instance* pInstance;
rabbit::Delegable* pDelegable; rabbit::Delegable* pDelegable;

160
rabbit/RefTable.cpp Normal file
View File

@ -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 <rabbit/RefTable.hpp>
#include <rabbit/Table.hpp>
#include <rabbit/squtils.hpp>
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();
//<<FIXME>>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;
}

42
rabbit/RefTable.hpp Normal file
View File

@ -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 <etk/types.hpp>
#include <rabbit/ObjectPtr.hpp>
#include <rabbit/Object.hpp>
#include <rabbit/Hash.hpp>
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;
};
}

221
rabbit/SharedState.cpp Normal file
View File

@ -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 <rabbit/SharedState.hpp>
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<int64_t> &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<rabbit::ObjectPtr>);
sq_new(_systemstrings,etk::Vector<rabbit::ObjectPtr>);
sq_new(_types,etk::Vector<rabbit::ObjectPtr>);
_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<rabbit::ObjectPtr>;
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;
}

85
rabbit/SharedState.hpp Normal file
View File

@ -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 <etk/types.hpp>
#include <rabbit/sqconfig.hpp>
#include <rabbit/RefTable.hpp>
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<rabbit::ObjectPtr> *_metamethods;
rabbit::ObjectPtr _metamethodsmap;
etk::Vector<rabbit::ObjectPtr> *_systemstrings;
etk::Vector<rabbit::ObjectPtr> *_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<int64_t> &res,const rabbit::Char *typemask);
}

45
rabbit/String.cpp Normal file
View File

@ -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/String.hpp>
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;
}

32
rabbit/String.hpp Normal file
View File

@ -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 <etk/types.hpp>
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];
};
}

102
rabbit/StringTable.cpp Normal file
View File

@ -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.hpp>
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<oldsize; i++){
rabbit::String *p = oldtable[i];
while(p){
rabbit::String *next = p->_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
}

33
rabbit/StringTable.hpp Normal file
View File

@ -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 <etk/types.hpp>
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)
}

View File

@ -5,17 +5,28 @@
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved * @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
* @license MPL-2 (see license file) * @license MPL-2 (see license file)
*/ */
#pragma once
#include <rabbit/Table.hpp>
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 <rabbit/sqpcheader.hpp>
#include <rabbit/VirtualMachine.hpp>
#include <rabbit/sqtable.hpp>
#include <rabbit/sqfuncproto.hpp>
#include <rabbit/sqclosure.hpp>
#define MINPOWER2 4 #define MINPOWER2 4
SQTable::SQTable(SQSharedState *ss,int64_t ninitialsize) rabbit::Table::rabbit::Table(rabbit::SharedState *ss,int64_t ninitialsize) {
{
int64_t pow2size=MINPOWER2; int64_t pow2size=MINPOWER2;
while(ninitialsize>pow2size)pow2size=pow2size<<1; while(ninitialsize>pow2size)pow2size=pow2size<<1;
allocNodes(pow2size); allocNodes(pow2size);
@ -23,9 +34,7 @@ SQTable::SQTable(SQSharedState *ss,int64_t ninitialsize)
_delegate = NULL; _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)); _HashNode *n = _get(key, HashObj(key) & (_numofnodes - 1));
if (n) { if (n) {
n->val.Null(); 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); _HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nsize);
for(int64_t i=0;i<nsize;i++){ for(int64_t i=0;i<nsize;i++){
@ -48,7 +57,7 @@ void SQTable::allocNodes(int64_t nsize)
_firstfree=&_nodes[_numofnodes-1]; _firstfree=&_nodes[_numofnodes-1];
} }
void SQTable::Rehash(bool force) void rabbit::Table::Rehash(bool force)
{ {
int64_t oldsize=_numofnodes; int64_t oldsize=_numofnodes;
//prevent problems with the integer division //prevent problems with the integer division
@ -75,9 +84,9 @@ void SQTable::Rehash(bool force)
SQ_FREE(nold,oldsize*sizeof(_HashNode)); SQ_FREE(nold,oldsize*sizeof(_HashNode));
} }
SQTable *SQTable::clone() rabbit::Table *rabbit::Table::clone()
{ {
SQTable *nt=create(NULL,_numofnodes); rabbit::Table *nt=create(NULL,_numofnodes);
#ifdef _FAST_CLONE #ifdef _FAST_CLONE
_HashNode *basesrc = _nodes; _HashNode *basesrc = _nodes;
_HashNode *basedst = nt->_nodes; _HashNode *basedst = nt->_nodes;
@ -110,7 +119,7 @@ SQTable *SQTable::clone()
return nt; 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) if(sq_type(key) == rabbit::OT_NULL)
return false; return false;
@ -121,10 +130,10 @@ bool SQTable::get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val)
} }
return false; 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); 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); _HashNode *n = _get(key, h);
if (n) { if (n) {
n->val = val; 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) { if(sq_type(mp->key) != rabbit::OT_NULL) {
n = _firstfree; /* get a free place */ 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 */ _HashNode *othern; /* main position of colliding node */
if (mp > n && (othern = &_nodes[mph]) != mp){ 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); 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); int64_t idx = (int64_t)translateIndex(refpos);
while (idx < _numofnodes) { 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)); _HashNode *n = _get(key, HashObj(key) & (_numofnodes - 1));
if (n) { if (n) {
@ -207,20 +216,72 @@ bool SQTable::set(const rabbit::ObjectPtr &key, const rabbit::ObjectPtr &val)
return false; 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(); } 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(); _clearNodes();
setDelegate(NULL); setDelegate(NULL);
} }
void SQTable::clear() void rabbit::Table::clear()
{ {
_clearNodes(); _clearNodes();
_usednodes = 0; _usednodes = 0;
Rehash(true); 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);
}

55
rabbit/Table.hpp Normal file
View File

@ -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 <etk/types.hpp>
#include <rabbit/Delegable.hpp>
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();
};
}

View File

@ -10,14 +10,14 @@
namespace rabbit { namespace rabbit {
class UserData : public rabbit::Delegable { class UserData : public rabbit::Delegable {
public: public:
UserData(SQSharedState *ss) { UserData(rabbit::SharedState *ss) {
_delegate = 0; _delegate = 0;
m_hook = NULL; m_hook = NULL;
} }
~UserData() { ~UserData() {
setDelegate(NULL); 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); UserData* ud = (UserData*)SQ_MALLOC(sq_aligning(sizeof(UserData))+size);
new (ud) UserData(ss); new (ud) UserData(ss);
ud->m_size = size; ud->m_size = size;

View File

@ -12,8 +12,8 @@
#include <rabbit/VirtualMachine.hpp> #include <rabbit/VirtualMachine.hpp>
#include <rabbit/sqfuncproto.hpp> #include <rabbit/sqfuncproto.hpp>
#include <rabbit/sqclosure.hpp> #include <rabbit/sqclosure.hpp>
#include <rabbit/sqstring.hpp>
#include <rabbit/sqtable.hpp>
#include <rabbit/UserData.hpp> #include <rabbit/UserData.hpp>
#include <rabbit/Array.hpp> #include <rabbit/Array.hpp>
#include <rabbit/Instance.hpp> #include <rabbit/Instance.hpp>
@ -112,7 +112,7 @@ bool rabbit::VirtualMachine::ARITH_OP(uint64_t op,rabbit::ObjectPtr &trg,const r
return true; return true;
} }
rabbit::VirtualMachine::VirtualMachine(SQSharedState *ss) rabbit::VirtualMachine::VirtualMachine(rabbit::SharedState *ss)
{ {
_sharedstate=ss; _sharedstate=ss;
_suspended = SQFalse; _suspended = SQFalse;
@ -319,7 +319,7 @@ bool rabbit::VirtualMachine::toString(const rabbit::ObjectPtr &o,rabbit::ObjectP
default: 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)); 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; 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)); rabbit::Char *s = _sp(sq_rsl(l + ol + 1));
memcpy(s, _stringval(a), sq_rsl(l)); memcpy(s, _stringval(a), sq_rsl(l));
memcpy(s + l, _stringval(b), sq_rsl(ol)); 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; return true;
} }
@ -346,7 +346,7 @@ bool rabbit::VirtualMachine::typeOf(const rabbit::ObjectPtr &obj1,rabbit::Object
return callMetaMethod(closure,MT_TYPEOF,1,dest); 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; return true;
} }
@ -360,7 +360,7 @@ bool rabbit::VirtualMachine::init(rabbit::VirtualMachine *friendvm, int64_t stac
_stackbase = 0; _stackbase = 0;
_top = 0; _top = 0;
if(!friendvm) { if(!friendvm) {
_roottable = SQTable::create(_get_shared_state(this), 0); _roottable = rabbit::Table::create(_get_shared_state(this), 0);
sq_base_register(this); sq_base_register(this);
} }
else { else {
@ -901,7 +901,7 @@ exception_restore:
continue; continue;
case _OP_NEWOBJ: case _OP_NEWOBJ:
switch(arg3) { 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_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; case NOT_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue;
default: assert(0); 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) 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)) { switch(sq_type(self)) {
case rabbit::OT_CLASS: ddel = _class_ddel; break; case rabbit::OT_CLASS: ddel = _class_ddel; break;
case rabbit::OT_TABLE: ddel = _table_ddel; break; case rabbit::OT_TABLE: ddel = _table_ddel; break;

View File

@ -13,6 +13,7 @@
#include <rabbit/sqconfig.hpp> #include <rabbit/sqconfig.hpp>
#include <rabbit/ExceptionTrap.hpp> #include <rabbit/ExceptionTrap.hpp>
#include <rabbit/MetaMethod.hpp> #include <rabbit/MetaMethod.hpp>
#include <rabbit/ObjectPtr.hpp>
#define MAX_NATIVE_CALLS 100 #define MAX_NATIVE_CALLS 100
@ -58,7 +59,7 @@ namespace rabbit {
ET_RESUME_VM, ET_RESUME_VM,
ET_RESUME_THROW_VM ET_RESUME_THROW_VM
}; };
VirtualMachine(SQSharedState *ss); VirtualMachine(rabbit::SharedState *ss);
~VirtualMachine(); ~VirtualMachine();
bool init(VirtualMachine *friendvm, int64_t stacksize); 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); 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); 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); static bool isEqual(const rabbit::ObjectPtr &o1,const rabbit::ObjectPtr &o2,bool &res);
bool toString(const rabbit::ObjectPtr &o,rabbit::ObjectPtr &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, ...); void raise_error(const rabbit::Char *s, ...);
@ -172,7 +173,7 @@ namespace rabbit {
callInfo *ci; callInfo *ci;
rabbit::UserPointer _foreignptr; rabbit::UserPointer _foreignptr;
//VMs sharing the same state //VMs sharing the same state
SQSharedState *_sharedstate; rabbit::SharedState *_sharedstate;
int64_t _nnativecalls; int64_t _nnativecalls;
int64_t _nmetamethodscall; int64_t _nmetamethodscall;
SQRELEASEHOOK _releasehook; SQRELEASEHOOK _releasehook;

View File

@ -41,6 +41,7 @@
#define SQ_BYTECODE_STREAM_TAG 0xFAFA #define SQ_BYTECODE_STREAM_TAG 0xFAFA
#include <rabbit/Object.hpp> #include <rabbit/Object.hpp>
#include <rabbit/Hash.hpp>
@ -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::ObjectType sq_gettype(rabbit::VirtualMachine* v,int64_t idx);
RABBIT_API rabbit::Result sq_typeof(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 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::Result sq_getbase(rabbit::VirtualMachine* v,int64_t idx);
RABBIT_API rabbit::Bool sq_instanceof(rabbit::VirtualMachine* v); RABBIT_API rabbit::Bool sq_instanceof(rabbit::VirtualMachine* v);
RABBIT_API rabbit::Result sq_tostring(rabbit::VirtualMachine* v,int64_t idx); RABBIT_API rabbit::Result sq_tostring(rabbit::VirtualMachine* v,int64_t idx);

View File

@ -7,8 +7,8 @@
*/ */
#include <rabbit/sqpcheader.hpp> #include <rabbit/sqpcheader.hpp>
#include <rabbit/VirtualMachine.hpp> #include <rabbit/VirtualMachine.hpp>
#include <rabbit/sqstring.hpp>
#include <rabbit/sqtable.hpp>
#include <rabbit/Array.hpp> #include <rabbit/Array.hpp>
#include <rabbit/sqfuncproto.hpp> #include <rabbit/sqfuncproto.hpp>
#include <rabbit/sqclosure.hpp> #include <rabbit/sqclosure.hpp>
@ -47,8 +47,8 @@ int64_t sq_aux_invalidtype(rabbit::VirtualMachine* v,rabbit::ObjectType type)
rabbit::VirtualMachine* sq_open(int64_t initialstacksize) rabbit::VirtualMachine* sq_open(int64_t initialstacksize)
{ {
SQSharedState *ss; rabbit::SharedState *ss;
sq_new(ss, SQSharedState); sq_new(ss, rabbit::SharedState);
ss->init(); ss->init();
char* allocatedData = (char*)SQ_MALLOC(sizeof(rabbit::VirtualMachine)); 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) rabbit::VirtualMachine* sq_newthread(rabbit::VirtualMachine* friendvm, int64_t initialstacksize)
{ {
SQSharedState *ss; rabbit::SharedState *ss;
ss=_get_shared_state(friendvm); ss=_get_shared_state(friendvm);
char* allocatedData = (char*)SQ_MALLOC(sizeof(rabbit::VirtualMachine)); char* allocatedData = (char*)SQ_MALLOC(sizeof(rabbit::VirtualMachine));
@ -123,9 +123,9 @@ void sq_setdebughook(rabbit::VirtualMachine* v)
void sq_close(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(); _thread(ss->_root_vm)->finalize();
sq_delete(ss, SQSharedState); sq_delete(ss, rabbit::SharedState);
} }
int64_t sq_getversion() 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) void sq_pushstring(rabbit::VirtualMachine* v,const rabbit::Char *s,int64_t len)
{ {
if(s) 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(); else v->pushNull();
} }
@ -269,12 +269,12 @@ rabbit::UserPointer sq_newuserdata(rabbit::VirtualMachine* v,uint64_t size)
void sq_newtable(rabbit::VirtualMachine* v) 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) 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) 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); rabbit::Object o = stack_get(v, idx);
if(sq_isnativeclosure(o)) { if(sq_isnativeclosure(o)) {
SQNativeClosure *nc = _nativeclosure(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_OK;
} }
return sq_throwerror(v,_SC("the object is not a nativeclosure")); 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); rabbit::ObjectPtr &o = stack_get(v, idx);
return HashObj(o); return HashObj(o);
@ -1133,7 +1133,7 @@ void sq_resetobject(rabbit::Object *po)
rabbit::Result sq_throwerror(rabbit::VirtualMachine* v,const rabbit::Char *err) 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; return SQ_ERROR;
} }
@ -1446,7 +1446,7 @@ rabbit::Result sq_getmemberhandle(rabbit::VirtualMachine* v,int64_t idx,rabbit::
rabbit::ObjectPtr *o = NULL; rabbit::ObjectPtr *o = NULL;
_GETSAFE_OBJ(v, idx, rabbit::OT_CLASS,o); _GETSAFE_OBJ(v, idx, rabbit::OT_CLASS,o);
rabbit::ObjectPtr &key = stack_get(v,-1); rabbit::ObjectPtr &key = stack_get(v,-1);
SQTable *m = _class(*o)->_members; rabbit::Table *m = _class(*o)->_members;
rabbit::ObjectPtr val; rabbit::ObjectPtr val;
if(m->get(key,val)) { if(m->get(key,val)) {
handle->_static = _isfield(val) ? SQFalse : SQTrue; 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) 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) { switch(t) {
case rabbit::OT_TABLE: v->push(ss->_table_default_delegate); break; case rabbit::OT_TABLE: v->push(ss->_table_default_delegate); break;
case rabbit::OT_ARRAY: v->push(ss->_array_default_delegate); break; case rabbit::OT_ARRAY: v->push(ss->_array_default_delegate); break;

View File

@ -7,8 +7,8 @@
*/ */
#include <rabbit/sqpcheader.hpp> #include <rabbit/sqpcheader.hpp>
#include <rabbit/VirtualMachine.hpp> #include <rabbit/VirtualMachine.hpp>
#include <rabbit/sqstring.hpp>
#include <rabbit/sqtable.hpp>
#include <rabbit/Array.hpp> #include <rabbit/Array.hpp>
#include <rabbit/sqfuncproto.hpp> #include <rabbit/sqfuncproto.hpp>
#include <rabbit/sqclosure.hpp> #include <rabbit/sqclosure.hpp>
@ -258,7 +258,7 @@ static int64_t base_array(rabbit::VirtualMachine* v)
static int64_t base_type(rabbit::VirtualMachine* v) static int64_t base_type(rabbit::VirtualMachine* v)
{ {
rabbit::ObjectPtr &o = stack_get(v,2); 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; return 1;
} }
@ -411,7 +411,7 @@ static int64_t number_delegate_tochar(rabbit::VirtualMachine* v)
{ {
rabbit::Object &o=stack_get(v,1); rabbit::Object &o=stack_get(v,1);
rabbit::Char c = (rabbit::Char)tointeger(o); 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; return 1;
} }
@ -465,8 +465,8 @@ static int64_t table_getdelegate(rabbit::VirtualMachine* v)
static int64_t table_filter(rabbit::VirtualMachine* v) static int64_t table_filter(rabbit::VirtualMachine* v)
{ {
rabbit::Object &o = stack_get(v,1); rabbit::Object &o = stack_get(v,1);
SQTable *tbl = _table(o); rabbit::Table *tbl = _table(o);
rabbit::ObjectPtr ret = SQTable::create(_get_shared_state(v),0); rabbit::ObjectPtr ret = rabbit::Table::create(_get_shared_state(v),0);
rabbit::ObjectPtr itr, key, val; rabbit::ObjectPtr itr, key, val;
int64_t nitr; 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("len"),default_delegate_len,1, _SC("t")},
{_SC("rawget"),container_rawget,2, _SC("t")}, {_SC("rawget"),container_rawget,2, _SC("t")},
{_SC("rawset"),container_rawset,3, _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("len"),default_delegate_len,1, _SC("a")},
{_SC("append"),array_append,2, _SC("a")}, {_SC("append"),array_append,2, _SC("a")},
{_SC("extend"),array_extend,2, _SC("aa")}, {_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 < 0)eidx = slen + eidx;
if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes")); if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes"));
if(eidx > slen || sidx < 0) return sq_throwerror(v, _SC("slice out of range")); 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; 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))); \ rabbit::Char *snew=(_get_shared_state(v)->getScratchPad(sq_rsl(len))); \
memcpy(snew,sthis,sq_rsl(len));\ memcpy(snew,sthis,sq_rsl(len));\
for(int64_t i=sidx;i<eidx;i++) snew[i] = func(sthis[i]); \ for(int64_t i=sidx;i<eidx;i++) snew[i] = func(sthis[i]); \
v->push(SQString::create(_get_shared_state(v),snew,len)); \ v->push(rabbit::String::create(_get_shared_state(v),snew,len)); \
return 1; \ return 1; \
} }
@ -889,7 +889,7 @@ static int64_t string_find(rabbit::VirtualMachine* v)
STRING_TOFUNCZ(tolower) STRING_TOFUNCZ(tolower)
STRING_TOFUNCZ(toupper) 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("len"),default_delegate_len,1, _SC("s")},
{_SC("tointeger"),default_delegate_tointeger,-1, _SC("sn")}, {_SC("tointeger"),default_delegate_tointeger,-1, _SC("sn")},
{_SC("tofloat"),default_delegate_tofloat,1, _SC("s")}, {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")},
@ -903,7 +903,7 @@ const rabbit::RegFunction SQSharedState::_string_default_delegate_funcz[]={
}; };
//INTEGER DEFAULT DELEGATE////////////////////////// //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("tointeger"),default_delegate_tointeger,1, _SC("n|b")},
{_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")}, {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")},
{_SC("tostring"),default_delegate_tostring,1, _SC(".")}, {_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) { static int64_t closure_getinfos(rabbit::VirtualMachine* v) {
rabbit::Object o = stack_get(v,1); 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) { if(sq_type(o) == rabbit::OT_CLOSURE) {
SQFunctionProto *f = _closure(o)->_function; SQFunctionProto *f = _closure(o)->_function;
int64_t nparams = f->_nparameters + (f->_varparams?1:0); 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]); _array(defparams)->set((int64_t)j,_closure(o)->_defaultparams[j]);
} }
if(f->_varparams) { 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(rabbit::String::create(_get_shared_state(v),_SC("native"),-1),false);
res->newSlot(SQString::create(_get_shared_state(v),_SC("name"),-1),f->_name); res->newSlot(rabbit::String::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(rabbit::String::create(_get_shared_state(v),_SC("src"),-1),f->_sourcename);
res->newSlot(SQString::create(_get_shared_state(v),_SC("parameters"),-1),params); res->newSlot(rabbit::String::create(_get_shared_state(v),_SC("parameters"),-1),params);
res->newSlot(SQString::create(_get_shared_state(v),_SC("varargs"),-1),f->_varparams); res->newSlot(rabbit::String::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("defparams"),-1),defparams);
} }
else { //rabbit::OT_NATIVECLOSURE else { //rabbit::OT_NATIVECLOSURE
SQNativeClosure *nc = _nativeclosure(o); SQNativeClosure *nc = _nativeclosure(o);
res->newSlot(SQString::create(_get_shared_state(v),_SC("native"),-1),true); res->newSlot(rabbit::String::create(_get_shared_state(v),_SC("native"),-1),true);
res->newSlot(SQString::create(_get_shared_state(v),_SC("name"),-1),nc->_name); res->newSlot(rabbit::String::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("paramscheck"),-1),nc->_nparamscheck);
rabbit::ObjectPtr typecheck; rabbit::ObjectPtr typecheck;
if(nc->_typecheck.size() > 0) { if(nc->_typecheck.size() > 0) {
typecheck = typecheck =
@ -1005,7 +1005,7 @@ static int64_t closure_getinfos(rabbit::VirtualMachine* v) {
_array(typecheck)->set((int64_t)n,nc->_typecheck[n]); _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); v->push(res);
return 1; 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("call"),closure_call,-1, _SC("c")},
{_SC("pcall"),closure_pcall,-1, _SC("c")}, {_SC("pcall"),closure_pcall,-1, _SC("c")},
{_SC("acall"),closure_acall,2, _SC("ca")}, {_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); rabbit::Object &o=stack_get(v,1);
switch(_generator(o)->_state){ switch(_generator(o)->_state){
case SQGenerator::eSuspended:v->push(SQString::create(_get_shared_state(v),_SC("suspended")));break; case SQGenerator::eSuspended:v->push(rabbit::String::create(_get_shared_state(v),_SC("suspended")));break;
case SQGenerator::eRunning:v->push(SQString::create(_get_shared_state(v),_SC("running")));break; case SQGenerator::eRunning:v->push(rabbit::String::create(_get_shared_state(v),_SC("running")));break;
case SQGenerator::eDead:v->push(SQString::create(_get_shared_state(v),_SC("dead")));break; case SQGenerator::eDead:v->push(rabbit::String::create(_get_shared_state(v),_SC("dead")));break;
} }
return 1; 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("getstatus"),generator_getstatus,1, _SC("g")},
{_SC("weakref"),obj_delegate_weakref,1, NULL }, {_SC("weakref"),obj_delegate_weakref,1, NULL },
{_SC("tostring"),default_delegate_tostring,1, _SC(".")}, {_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")); 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("call"), thread_call, -1, _SC("v")},
{_SC("wakeup"), thread_wakeup, -1, _SC("v")}, {_SC("wakeup"), thread_wakeup, -1, _SC("v")},
{_SC("wakeupthrow"), thread_wakeupthrow, -2, _SC("v.b")}, {_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; 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("getattributes"), class_getattributes, 2, _SC("y.")},
{_SC("setattributes"), class_setattributes, 3, _SC("y..")}, {_SC("setattributes"), class_setattributes, 3, _SC("y..")},
{_SC("rawget"),container_rawget,2, _SC("y")}, {_SC("rawget"),container_rawget,2, _SC("y")},
@ -1281,7 +1281,7 @@ static int64_t instance_getclass(rabbit::VirtualMachine* v)
return SQ_ERROR; 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("getclass"), instance_getclass, 1, _SC("x")},
{_SC("rawget"),container_rawget,2, _SC("x")}, {_SC("rawget"),container_rawget,2, _SC("x")},
{_SC("rawset"),container_rawset,3, _SC("x")}, {_SC("rawset"),container_rawset,3, _SC("x")},
@ -1298,7 +1298,7 @@ static int64_t weakref_ref(rabbit::VirtualMachine* v)
return 1; 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("ref"),weakref_ref,1, _SC("r")},
{_SC("weakref"),obj_delegate_weakref,1, NULL }, {_SC("weakref"),obj_delegate_weakref,1, NULL },
{_SC("tostring"),default_delegate_tostring,1, _SC(".")}, {_SC("tostring"),default_delegate_tostring,1, _SC(".")},

View File

@ -16,14 +16,14 @@ struct SQFunctionProto;
struct SQClosure : public rabbit::RefCounted struct SQClosure : public rabbit::RefCounted
{ {
private: private:
SQClosure(SQSharedState *ss,SQFunctionProto *func){ SQClosure(rabbit::SharedState *ss,SQFunctionProto *func){
_function = func; _function = func;
__ObjaddRef(_function); _base = NULL; __ObjaddRef(_function); _base = NULL;
_env = NULL; _env = NULL;
_root=NULL; _root=NULL;
} }
public: 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); int64_t size = _CALC_CLOSURE_SIZE(func);
SQClosure *nc=(SQClosure*)SQ_MALLOC(size); SQClosure *nc=(SQClosure*)SQ_MALLOC(size);
new (nc) SQClosure(ss,func); new (nc) SQClosure(ss,func);
@ -77,13 +77,13 @@ struct SQOuter : public rabbit::RefCounted
{ {
private: private:
SQOuter(SQSharedState *ss, rabbit::ObjectPtr *outer){ SQOuter(rabbit::SharedState *ss, rabbit::ObjectPtr *outer){
_valptr = outer; _valptr = outer;
_next = NULL; _next = NULL;
} }
public: 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)); SQOuter *nc = (SQOuter*)SQ_MALLOC(sizeof(SQOuter));
new (nc) SQOuter(ss, outer); new (nc) SQOuter(ss, outer);
@ -110,13 +110,13 @@ struct SQGenerator : public rabbit::RefCounted
{ {
enum SQGeneratorState{eRunning,eSuspended,eDead}; enum SQGeneratorState{eRunning,eSuspended,eDead};
private: private:
SQGenerator(SQSharedState *ss,SQClosure *closure){ SQGenerator(rabbit::SharedState *ss,SQClosure *closure){
_closure=closure; _closure=closure;
_state=eRunning; _state=eRunning;
_ci._generator=NULL; _ci._generator=NULL;
} }
public: public:
static SQGenerator *create(SQSharedState *ss,SQClosure *closure){ static SQGenerator *create(rabbit::SharedState *ss,SQClosure *closure){
SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator)); SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));
new (nc) SQGenerator(ss,closure); new (nc) SQGenerator(ss,closure);
return nc; return nc;
@ -147,12 +147,12 @@ public:
struct SQNativeClosure : public rabbit::RefCounted struct SQNativeClosure : public rabbit::RefCounted
{ {
private: private:
SQNativeClosure(SQSharedState *ss,SQFUNCTION func){ SQNativeClosure(rabbit::SharedState *ss,SQFUNCTION func){
_function=func; _function=func;
_env = NULL; _env = NULL;
} }
public: 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); int64_t size = _CALC_NATVIVECLOSURE_SIZE(nouters);
SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(size); SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(size);

View File

@ -10,13 +10,13 @@
#include <stdarg.h> #include <stdarg.h>
#include <setjmp.h> #include <setjmp.h>
#include <rabbit/sqopcodes.hpp> #include <rabbit/sqopcodes.hpp>
#include <rabbit/sqstring.hpp>
#include <rabbit/sqfuncproto.hpp> #include <rabbit/sqfuncproto.hpp>
#include <rabbit/sqcompiler.hpp> #include <rabbit/sqcompiler.hpp>
#include <rabbit/sqfuncstate.hpp> #include <rabbit/sqfuncstate.hpp>
#include <rabbit/sqlexer.hpp> #include <rabbit/sqlexer.hpp>
#include <rabbit/VirtualMachine.hpp> #include <rabbit/VirtualMachine.hpp>
#include <rabbit/sqtable.hpp>
#define EXPR 1 #define EXPR 1
#define OBJECT 2 #define OBJECT 2
@ -80,7 +80,7 @@ public:
{ {
_vm=v; _vm=v;
_lex.init(_get_shared_state(v), rg, up,Throwerror,this); _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; _lineinfo = lineinfo;_raiseerror = raiseerror;
_scope.outers = 0; _scope.outers = 0;
_scope.stacksize = 0; _scope.stacksize = 0;
@ -171,7 +171,7 @@ public:
_debugop = 0; _debugop = 0;
SQFuncState funcstate(_get_shared_state(_vm), NULL,Throwerror,this); 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 = &funcstate;
_fs->addParameter(_fs->createString(_SC("this"))); _fs->addParameter(_fs->createString(_SC("this")));
_fs->addParameter(_fs->createString(_SC("vargv"))); _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"), _get_shared_state(_vm)->_compilererrorhandler(_vm, _compilererror, sq_type(_sourcename) == rabbit::OT_STRING?_stringval(_sourcename):_SC("unknown"),
_lex._currentline, _lex._currentcolumn); _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 false;
} }
return true; return true;
@ -305,7 +305,7 @@ public:
Expect('='); Expect('=');
rabbit::Object val = ExpectScalar(); rabbit::Object val = ExpectScalar();
OptionalSemicolon(); OptionalSemicolon();
SQTable *enums = _table(_get_shared_state(_vm)->_consts); rabbit::Table *enums = _table(_get_shared_state(_vm)->_consts);
rabbit::ObjectPtr strongid = id; rabbit::ObjectPtr strongid = id;
enums->newSlot(strongid,rabbit::ObjectPtr(val)); enums->newSlot(strongid,rabbit::ObjectPtr(val));
strongid.Null(); strongid.Null();
@ -1381,7 +1381,7 @@ public:
_table(table)->newSlot(rabbit::ObjectPtr(key),rabbit::ObjectPtr(val)); _table(table)->newSlot(rabbit::ObjectPtr(key),rabbit::ObjectPtr(val));
if(_token == ',') Lex(); if(_token == ',') Lex();
} }
SQTable *enums = _table(_get_shared_state(_vm)->_consts); rabbit::Table *enums = _table(_get_shared_state(_vm)->_consts);
rabbit::ObjectPtr strongid = id; rabbit::ObjectPtr strongid = id;
enums->newSlot(rabbit::ObjectPtr(strongid),rabbit::ObjectPtr(table)); enums->newSlot(rabbit::ObjectPtr(strongid),rabbit::ObjectPtr(table));
strongid.Null(); strongid.Null();

View File

@ -9,10 +9,6 @@
#include <etk/types.hpp> #include <etk/types.hpp>
// should be the same size of a pointer
using SQHash = size_t;
#ifdef SQUSEDOUBLE #ifdef SQUSEDOUBLE
typedef double float_t; typedef double float_t;
#else #else
@ -31,6 +27,9 @@ typedef uint64_t SQRawObjectVal; //is 32 bits on 32 bits builds and 64 bits othe
#define SQ_ALIGNMENT 8 #define SQ_ALIGNMENT 8
#endif #endif
//max number of character for a printed number
#define NUMBER_MAX_CHAR 50
namespace rabbit { namespace rabbit {
using UserPointer = void*; using UserPointer = void*;
using Bool = uint64_t; using Bool = uint64_t;
@ -125,14 +124,11 @@ namespace rabbit {
#define SQTrue (1) #define SQTrue (1)
#define SQFalse (0) #define SQFalse (0)
struct SQTable;
struct SQString;
struct SQClosure; struct SQClosure;
struct SQGenerator; struct SQGenerator;
struct SQNativeClosure; struct SQNativeClosure;
struct SQFunctionProto; struct SQFunctionProto;
struct SQOuter; struct SQOuter;
struct SQSharedState;
namespace rabbit { namespace rabbit {
class UserData; class UserData;
class Array; class Array;
@ -145,4 +141,7 @@ namespace rabbit {
class MemberHandle; class MemberHandle;
class Instance; class Instance;
class Class; class Class;
class Table;
class String;
class SharedState;
} }

View File

@ -11,7 +11,7 @@
#include <rabbit/VirtualMachine.hpp> #include <rabbit/VirtualMachine.hpp>
#include <rabbit/sqfuncproto.hpp> #include <rabbit/sqfuncproto.hpp>
#include <rabbit/sqclosure.hpp> #include <rabbit/sqclosure.hpp>
#include <rabbit/sqstring.hpp>
#include <rabbit/FunctionInfo.hpp> #include <rabbit/FunctionInfo.hpp>
#include <rabbit/StackInfos.hpp> #include <rabbit/StackInfos.hpp>
@ -70,7 +70,7 @@ void rabbit::VirtualMachine::raise_error(const rabbit::Char *s, ...)
int64_t buffersize = (int64_t)scstrlen(s)+(NUMBER_MAX_CHAR*2); int64_t buffersize = (int64_t)scstrlen(s)+(NUMBER_MAX_CHAR*2);
scvsprintf(_sp(sq_rsl(buffersize)),buffersize, s, vl); scvsprintf(_sp(sq_rsl(buffersize)),buffersize, s, vl);
va_end(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) void rabbit::VirtualMachine::raise_error(const rabbit::ObjectPtr &desc)
@ -78,20 +78,20 @@ void rabbit::VirtualMachine::raise_error(const rabbit::ObjectPtr &desc)
_lasterror = desc; _lasterror = desc;
} }
SQString *rabbit::VirtualMachine::printObjVal(const rabbit::ObjectPtr &o) rabbit::String *rabbit::VirtualMachine::printObjVal(const rabbit::ObjectPtr &o)
{ {
switch(sq_type(o)) { switch(sq_type(o)) {
case rabbit::OT_STRING: return _string(o); case rabbit::OT_STRING: return _string(o);
case rabbit::OT_INTEGER: case rabbit::OT_INTEGER:
scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)),sq_rsl(NUMBER_MAX_CHAR), _PRINT_INT_FMT, _integer(o)); 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; break;
case rabbit::OT_FLOAT: case rabbit::OT_FLOAT:
scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)), sq_rsl(NUMBER_MAX_CHAR), _SC("%.14g"), _float(o)); 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; break;
default: 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) 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; int64_t found = 0;
for(int64_t i=0; i<16; i++) for(int64_t i=0; i<16; i++)
{ {
int64_t mask = ((int64_t)1) << i; int64_t mask = ((int64_t)1) << i;
if(typemask & (mask)) { 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 ++; 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)); raise_error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((rabbit::ObjectType)type), _stringval(exptypes));

View File

@ -67,11 +67,11 @@ typedef etk::Vector<SQLineInfo> SQLineInfoVec;
struct SQFunctionProto : public rabbit::RefCounted struct SQFunctionProto : public rabbit::RefCounted
{ {
private: private:
SQFunctionProto(SQSharedState *ss); SQFunctionProto(rabbit::SharedState *ss);
~SQFunctionProto(); ~SQFunctionProto();
public: 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 nliterals,int64_t nparameters,
int64_t nfunctions,int64_t noutervalues, int64_t nfunctions,int64_t noutervalues,
int64_t nlineinfos,int64_t nlocalvarinfos,int64_t ndefaultparams) int64_t nlineinfos,int64_t nlocalvarinfos,int64_t ndefaultparams)

View File

@ -9,9 +9,9 @@
#include <rabbit/sqpcheader.hpp> #include <rabbit/sqpcheader.hpp>
#ifndef NO_COMPILER #ifndef NO_COMPILER
#include <rabbit/sqcompiler.hpp> #include <rabbit/sqcompiler.hpp>
#include <rabbit/sqstring.hpp>
#include <rabbit/sqfuncproto.hpp> #include <rabbit/sqfuncproto.hpp>
#include <rabbit/sqtable.hpp>
#include <rabbit/sqopcodes.hpp> #include <rabbit/sqopcodes.hpp>
#include <rabbit/sqfuncstate.hpp> #include <rabbit/sqfuncstate.hpp>
@ -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; _nliterals = 0;
_literals = SQTable::create(ss,0); _literals = rabbit::Table::create(ss,0);
_strings = SQTable::create(ss,0); _strings = rabbit::Table::create(ss,0);
_sharedstate = ss; _sharedstate = ss;
_lastline = 0; _lastline = 0;
_optimization = true; _optimization = true;
@ -586,14 +586,14 @@ void SQFuncState::addInstruction(SQInstruction &i)
rabbit::Object SQFuncState::createString(const rabbit::Char *s,int64_t len) 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); _table(_strings)->newSlot(ns,(int64_t)1);
return ns; return ns;
} }
rabbit::Object SQFuncState::createTable() 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); _table(_strings)->newSlot(nt,(int64_t)1);
return nt; return nt;
} }
@ -632,7 +632,7 @@ SQFunctionProto *SQFuncState::buildProto()
return f; return f;
} }
SQFuncState *SQFuncState::pushChildState(SQSharedState *ss) SQFuncState *SQFuncState::pushChildState(rabbit::SharedState *ss)
{ {
SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState)); SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState));
new (child) SQFuncState(ss,this,_errfunc,_errtarget); new (child) SQFuncState(ss,this,_errfunc,_errtarget);

View File

@ -11,13 +11,13 @@
struct SQFuncState struct SQFuncState
{ {
SQFuncState(SQSharedState *ss,SQFuncState *parent,compilererrorFunc efunc,void *ed); SQFuncState(rabbit::SharedState *ss,SQFuncState *parent,compilererrorFunc efunc,void *ed);
~SQFuncState(); ~SQFuncState();
#ifdef _DEBUG_DUMP #ifdef _DEBUG_DUMP
void dump(SQFunctionProto *func); void dump(SQFunctionProto *func);
#endif #endif
void error(const rabbit::Char *err); void error(const rabbit::Char *err);
SQFuncState *pushChildState(SQSharedState *ss); SQFuncState *pushChildState(rabbit::SharedState *ss);
void popChildState(); 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(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); void addInstruction(SQInstruction &i);
@ -82,13 +82,13 @@ struct SQFuncState
int64_t _traps; //contains number of nested exception traps int64_t _traps; //contains number of nested exception traps
int64_t _outers; int64_t _outers;
bool _optimization; bool _optimization;
SQSharedState *_sharedstate; rabbit::SharedState *_sharedstate;
etk::Vector<SQFuncState*> _childstates; etk::Vector<SQFuncState*> _childstates;
int64_t getConstant(const rabbit::Object &cons); int64_t getConstant(const rabbit::Object &cons);
private: private:
compilererrorFunc _errfunc; compilererrorFunc _errfunc;
void *_errtarget; void *_errtarget;
SQSharedState *_ss; rabbit::SharedState *_ss;
}; };

View File

@ -9,8 +9,8 @@
#include <rabbit/sqpcheader.hpp> #include <rabbit/sqpcheader.hpp>
#include <ctype.h> #include <ctype.h>
#include <stdlib.h> #include <stdlib.h>
#include <rabbit/sqtable.hpp>
#include <rabbit/sqstring.hpp>
#include <rabbit/sqcompiler.hpp> #include <rabbit/sqcompiler.hpp>
#include <rabbit/sqlexer.hpp> #include <rabbit/sqlexer.hpp>
@ -21,7 +21,7 @@
#define INIT_TEMP_STRING() { _longstr.resize(0);} #define INIT_TEMP_STRING() { _longstr.resize(0);}
#define APPEND_CHAR(c) { _longstr.pushBack(c);} #define APPEND_CHAR(c) { _longstr.pushBack(c);}
#define TERMINATE_BUFFER() {_longstr.pushBack(_SC('\0'));} #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(){}
SQLexer::~SQLexer() SQLexer::~SQLexer()
@ -29,12 +29,12 @@ SQLexer::~SQLexer()
_keywords->release(); _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; _errfunc = efunc;
_errtarget = ed; _errtarget = ed;
_sharedstate = ss; _sharedstate = ss;
_keywords = SQTable::create(ss, 37); _keywords = rabbit::Table::create(ss, 37);
ADD_KEYWORD(while, TK_WHILE); ADD_KEYWORD(while, TK_WHILE);
ADD_KEYWORD(do, TK_DO); ADD_KEYWORD(do, TK_DO);
ADD_KEYWORD(if, TK_IF); ADD_KEYWORD(if, TK_IF);

View File

@ -17,7 +17,7 @@ struct SQLexer
{ {
SQLexer(); 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); void error(const rabbit::Char *err);
int64_t Lex(); int64_t Lex();
const rabbit::Char *tok2Str(int64_t tok); const rabbit::Char *tok2Str(int64_t tok);
@ -38,7 +38,7 @@ private:
#endif #endif
int64_t processStringHexEscape(rabbit::Char *dest, int64_t maxdigits); int64_t processStringHexEscape(rabbit::Char *dest, int64_t maxdigits);
int64_t _curtoken; int64_t _curtoken;
SQTable *_keywords; rabbit::Table *_keywords;
rabbit::Bool _reached_eof; rabbit::Bool _reached_eof;
public: public:
int64_t _prevtoken; int64_t _prevtoken;
@ -51,7 +51,7 @@ public:
SQLEXREADFUNC _readf; SQLEXREADFUNC _readf;
rabbit::UserPointer _up; rabbit::UserPointer _up;
LexChar _currdata; LexChar _currdata;
SQSharedState *_sharedstate; rabbit::SharedState *_sharedstate;
etk::Vector<rabbit::Char> _longstr; etk::Vector<rabbit::Char> _longstr;
compilererrorFunc _errfunc; compilererrorFunc _errfunc;
void *_errtarget; void *_errtarget;

View File

@ -7,39 +7,14 @@
*/ */
#include <rabbit/sqpcheader.hpp> #include <rabbit/sqpcheader.hpp>
#include <rabbit/VirtualMachine.hpp> #include <rabbit/VirtualMachine.hpp>
#include <rabbit/sqstring.hpp>
#include <rabbit/Array.hpp> #include <rabbit/Array.hpp>
#include <rabbit/sqtable.hpp>
#include <rabbit/UserData.hpp> #include <rabbit/UserData.hpp>
#include <rabbit/sqfuncproto.hpp> #include <rabbit/sqfuncproto.hpp>
#include <rabbit/sqclosure.hpp> #include <rabbit/sqclosure.hpp>
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) bool SQGenerator::yield(rabbit::VirtualMachine *v,int64_t target)
{ {
if(_state==eSuspended) { v->raise_error(_SC("internal vm error, yielding dead generator")); return false;} 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; int64_t len;
_CHECK_IO(SafeRead(v,read,up,&len,sizeof(int64_t))); _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))); _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; break;
case rabbit::OT_INTEGER:{ case rabbit::OT_INTEGER:{
@ -301,7 +276,7 @@ bool SQClosure::load(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQREADFUNC
return true; return true;
} }
SQFunctionProto::SQFunctionProto(SQSharedState *ss) SQFunctionProto::SQFunctionProto(rabbit::SharedState *ss)
{ {
_stacksize=0; _stacksize=0;
_bgenerator=false; _bgenerator=false;

View File

@ -21,8 +21,6 @@
#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T')) #define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T'))
#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L')) #define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L'))
struct SQSharedState;
#define _CONSTRUCT_VECTOR(type, size, ptr) { \ #define _CONSTRUCT_VECTOR(type, size, ptr) { \
for(int64_t n = 0; n < ((int64_t)size); n++) { \ for(int64_t n = 0; n < ((int64_t)size); n++) { \
new (&ptr[n]) type(); \ new (&ptr[n]) type(); \
@ -46,14 +44,3 @@ struct SQSharedState;
vec[_n_].Null(); \ 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;
}

View File

@ -20,5 +20,5 @@
//rabbit stuff //rabbit stuff
#include <rabbit/rabbit.hpp> #include <rabbit/rabbit.hpp>
#include <rabbit/sqobject.hpp> #include <rabbit/sqobject.hpp>
#include <rabbit/sqstate.hpp>

View File

@ -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 <rabbit/sqpcheader.hpp>
#include <rabbit/sqopcodes.hpp>
#include <rabbit/VirtualMachine.hpp>
#include <rabbit/sqfuncproto.hpp>
#include <rabbit/sqclosure.hpp>
#include <rabbit/sqstring.hpp>
#include <rabbit/sqtable.hpp>
#include <rabbit/Array.hpp>
#include <rabbit/UserData.hpp>
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<int64_t> &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<rabbit::ObjectPtr>);
sq_new(_systemstrings,etk::Vector<rabbit::ObjectPtr>);
sq_new(_types,etk::Vector<rabbit::ObjectPtr>);
_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<rabbit::ObjectPtr>;
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();
//<<FIXME>>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<oldsize; i++){
SQString *p = oldtable[i];
while(p){
SQString *next = p->_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
}

View File

@ -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 <rabbit/squtils.hpp>
#include <rabbit/sqobject.hpp>
#include <rabbit/RegFunction.hpp>
#include <rabbit/ObjectPtr.hpp>
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<rabbit::ObjectPtr> *_metamethods;
rabbit::ObjectPtr _metamethodsmap;
etk::Vector<rabbit::ObjectPtr> *_systemstrings;
etk::Vector<rabbit::ObjectPtr> *_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<int64_t> &res,const rabbit::Char *typemask);

View File

@ -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];
};

View File

@ -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 <rabbit/sqstring.hpp>
#include <rabbit/Delegable.hpp>
#include <rabbit/squtils.hpp>
#include <etk/Allocator.hpp>
#include <rabbit/Object.hpp>
#include <rabbit/WeakRef.hpp>
#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);
}
};