[DEV] continue rework (little bug...)
This commit is contained in:
parent
394cc68950
commit
45e2df01f0
@ -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',
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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))))
|
||||||
}
|
|
||||||
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
13
rabbit/Hash.cpp
Normal 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
17
rabbit/Hash.hpp
Normal 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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -12,21 +12,20 @@
|
|||||||
|
|
||||||
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::Class *pClass;
|
rabbit::Table* pTable;
|
||||||
rabbit::Instance *pInstance;
|
rabbit::String* pString;
|
||||||
rabbit::Delegable *pDelegable;
|
rabbit::Class* pClass;
|
||||||
|
rabbit::Instance* pInstance;
|
||||||
|
rabbit::Delegable* pDelegable;
|
||||||
rabbit::UserPointer pUserPointer;
|
rabbit::UserPointer pUserPointer;
|
||||||
rabbit::WeakRef* pWeakRef;
|
rabbit::WeakRef* pWeakRef;
|
||||||
rabbit::VirtualMachine* pThread;
|
rabbit::VirtualMachine* pThread;
|
||||||
|
160
rabbit/RefTable.cpp
Normal file
160
rabbit/RefTable.cpp
Normal 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
42
rabbit/RefTable.hpp
Normal 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
221
rabbit/SharedState.cpp
Normal 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
85
rabbit/SharedState.hpp
Normal 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
45
rabbit/String.cpp
Normal 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
32
rabbit/String.hpp
Normal 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
102
rabbit/StringTable.cpp
Normal 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
33
rabbit/StringTable.hpp
Normal 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)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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
55
rabbit/Table.hpp
Normal 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();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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(".")},
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
}
|
}
|
@ -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));
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
|
||||||
}
|
|
@ -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>
|
|
||||||
|
|
||||||
|
@ -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
|
|
||||||
}
|
|
@ -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);
|
|
||||||
|
|
||||||
|
|
@ -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];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user