[DEV] rework Class ClassMethode
This commit is contained in:
parent
f882c9fedc
commit
394cc68950
@ -31,7 +31,9 @@ def configure(target, my_module):
|
||||
'rabbit/sqbaselib.cpp',
|
||||
'rabbit/sqapi.cpp',
|
||||
'rabbit/sqlexer.cpp',
|
||||
'rabbit/sqclass.cpp',
|
||||
'rabbit/Class.cpp',
|
||||
'rabbit/ClassMember.cpp',
|
||||
'rabbit/Instance.cpp',
|
||||
'rabbit/AutoDec.cpp',
|
||||
'rabbit/VirtualMachine.cpp',
|
||||
'rabbit/sqtable.cpp',
|
||||
@ -62,7 +64,9 @@ def configure(target, my_module):
|
||||
'etk-base',
|
||||
])
|
||||
my_module.add_header_file([
|
||||
'rabbit/sqclass.hpp',
|
||||
'rabbit/Class.hpp',
|
||||
'rabbit/ClassMember.hpp',
|
||||
'rabbit/Instance.hpp',
|
||||
'rabbit/AutoDec.hpp',
|
||||
'rabbit/VirtualMachine.hpp',
|
||||
'rabbit/sqstate.hpp',
|
||||
|
@ -5,17 +5,11 @@
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#include <rabbit/sqpcheader.hpp>
|
||||
#include <rabbit/VirtualMachine.hpp>
|
||||
#include <rabbit/sqtable.hpp>
|
||||
#include <rabbit/sqclass.hpp>
|
||||
#include <rabbit/sqfuncproto.hpp>
|
||||
#include <rabbit/sqclosure.hpp>
|
||||
#include <rabbit/MetaMethod.hpp>
|
||||
#include <rabbit/Class.hpp>
|
||||
#include <rabbit/Instance.hpp>
|
||||
|
||||
|
||||
SQClass::SQClass(SQSharedState *ss,SQClass *base)
|
||||
{
|
||||
rabbit::Class::Class(SQSharedState *ss,rabbit::Class *base) {
|
||||
_base = base;
|
||||
_typetag = 0;
|
||||
_hook = NULL;
|
||||
@ -34,7 +28,7 @@ SQClass::SQClass(SQSharedState *ss,SQClass *base)
|
||||
__ObjaddRef(_members);
|
||||
}
|
||||
|
||||
void SQClass::finalize() {
|
||||
void rabbit::Class::finalize() {
|
||||
_attributes.Null();
|
||||
_NULL_SQOBJECT_VECTOR(_defaultvalues,_defaultvalues.size());
|
||||
_methods.resize(0);
|
||||
@ -45,21 +39,21 @@ void SQClass::finalize() {
|
||||
}
|
||||
}
|
||||
|
||||
SQClass::~SQClass()
|
||||
{
|
||||
rabbit::Class::~Class() {
|
||||
finalize();
|
||||
}
|
||||
|
||||
bool SQClass::newSlot(SQSharedState *ss,const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val,bool bstatic)
|
||||
{
|
||||
bool rabbit::Class::newSlot(SQSharedState *ss,const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val,bool bstatic) {
|
||||
rabbit::ObjectPtr temp;
|
||||
bool belongs_to_static_table = sq_type(val) == rabbit::OT_CLOSURE
|
||||
|| sq_type(val) == rabbit::OT_NATIVECLOSURE
|
||||
|| bstatic;
|
||||
if(_locked && !belongs_to_static_table)
|
||||
return false; //the class already has an instance so cannot be modified
|
||||
if(_members->get(key,temp) && _isfield(temp)) //overrides the default value
|
||||
{
|
||||
if(_locked && !belongs_to_static_table) {
|
||||
//the class already has an instance so cannot be modified
|
||||
return false;
|
||||
}
|
||||
//overrides the default value
|
||||
if(_members->get(key,temp) && _isfield(temp)) {
|
||||
_defaultvalues[_member_idx(temp)].val = val;
|
||||
return true;
|
||||
}
|
||||
@ -69,8 +63,7 @@ bool SQClass::newSlot(SQSharedState *ss,const rabbit::ObjectPtr &key,const rabbi
|
||||
|| sq_type(val) == rabbit::OT_NATIVECLOSURE )
|
||||
&& (mmidx = ss->getMetaMethodIdxByName(key)) != -1) {
|
||||
_metamethods[mmidx] = val;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
rabbit::ObjectPtr theval = val;
|
||||
if(_base && sq_type(val) == rabbit::OT_CLOSURE) {
|
||||
theval = _closure(val)->clone();
|
||||
@ -83,39 +76,37 @@ bool SQClass::newSlot(SQSharedState *ss,const rabbit::ObjectPtr &key,const rabbi
|
||||
if(isconstructor) {
|
||||
_constructoridx = (int64_t)_methods.size();
|
||||
}
|
||||
SQClassMember m;
|
||||
rabbit::ClassMember m;
|
||||
m.val = theval;
|
||||
_members->newSlot(key,rabbit::ObjectPtr(_make_method_idx(_methods.size())));
|
||||
_methods.pushBack(m);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
_methods[_member_idx(temp)].val = theval;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
SQClassMember m;
|
||||
rabbit::ClassMember m;
|
||||
m.val = val;
|
||||
_members->newSlot(key,rabbit::ObjectPtr(_make_field_idx(_defaultvalues.size())));
|
||||
_defaultvalues.pushBack(m);
|
||||
return true;
|
||||
}
|
||||
|
||||
SQInstance *SQClass::createInstance()
|
||||
{
|
||||
if(!_locked) lock();
|
||||
return SQInstance::create(NULL,this);
|
||||
rabbit::Instance *rabbit::Class::createInstance() {
|
||||
if(!_locked) {
|
||||
lock();
|
||||
}
|
||||
return rabbit::Instance::create(NULL,this);
|
||||
}
|
||||
|
||||
int64_t SQClass::next(const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey, rabbit::ObjectPtr &outval)
|
||||
{
|
||||
int64_t rabbit::Class::next(const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey, rabbit::ObjectPtr &outval) {
|
||||
rabbit::ObjectPtr oval;
|
||||
int64_t idx = _members->next(false,refpos,outkey,oval);
|
||||
if(idx != -1) {
|
||||
if(_ismethod(oval)) {
|
||||
outval = _methods[_member_idx(oval)].val;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
rabbit::ObjectPtr &o = _defaultvalues[_member_idx(oval)].val;
|
||||
outval = _realval(o);
|
||||
}
|
||||
@ -123,21 +114,20 @@ int64_t SQClass::next(const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey
|
||||
return idx;
|
||||
}
|
||||
|
||||
bool SQClass::setAttributes(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val)
|
||||
{
|
||||
bool rabbit::Class::setAttributes(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val) {
|
||||
rabbit::ObjectPtr idx;
|
||||
if(_members->get(key,idx)) {
|
||||
if(_isfield(idx))
|
||||
if(_isfield(idx)) {
|
||||
_defaultvalues[_member_idx(idx)].attrs = val;
|
||||
else
|
||||
} else {
|
||||
_methods[_member_idx(idx)].attrs = val;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SQClass::getAttributes(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &outval)
|
||||
{
|
||||
bool rabbit::Class::getAttributes(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &outval) {
|
||||
rabbit::ObjectPtr idx;
|
||||
if(_members->get(key,idx)) {
|
||||
outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs);
|
||||
@ -146,65 +136,4 @@ bool SQClass::getAttributes(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &outv
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
void SQInstance::init(SQSharedState *ss)
|
||||
{
|
||||
_userpointer = NULL;
|
||||
_hook = NULL;
|
||||
__ObjaddRef(_class);
|
||||
_delegate = _class->_members;
|
||||
}
|
||||
|
||||
SQInstance::SQInstance(SQSharedState *ss, SQClass *c, int64_t memsize)
|
||||
{
|
||||
_memsize = memsize;
|
||||
_class = c;
|
||||
uint64_t nvalues = _class->_defaultvalues.size();
|
||||
for(uint64_t n = 0; n < nvalues; n++) {
|
||||
new (&_values[n]) rabbit::ObjectPtr(_class->_defaultvalues[n].val);
|
||||
}
|
||||
init(ss);
|
||||
}
|
||||
|
||||
SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, int64_t memsize)
|
||||
{
|
||||
_memsize = memsize;
|
||||
_class = i->_class;
|
||||
uint64_t nvalues = _class->_defaultvalues.size();
|
||||
for(uint64_t n = 0; n < nvalues; n++) {
|
||||
new (&_values[n]) rabbit::ObjectPtr(i->_values[n]);
|
||||
}
|
||||
init(ss);
|
||||
}
|
||||
|
||||
void SQInstance::finalize()
|
||||
{
|
||||
uint64_t nvalues = _class->_defaultvalues.size();
|
||||
__Objrelease(_class);
|
||||
_NULL_SQOBJECT_VECTOR(_values,nvalues);
|
||||
}
|
||||
|
||||
SQInstance::~SQInstance()
|
||||
{
|
||||
if(_class){ finalize(); } //if _class is null it was already finalized by the GC
|
||||
}
|
||||
|
||||
bool SQInstance::getMetaMethod(rabbit::VirtualMachine* SQ_UNUSED_ARG(v),rabbit::MetaMethod mm,rabbit::ObjectPtr &res)
|
||||
{
|
||||
if(sq_type(_class->_metamethods[mm]) != rabbit::OT_NULL) {
|
||||
res = _class->_metamethods[mm];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SQInstance::instanceOf(SQClass *trg)
|
||||
{
|
||||
SQClass *parent = _class;
|
||||
while(parent != NULL) {
|
||||
if(parent == trg)
|
||||
return true;
|
||||
parent = parent->_base;
|
||||
}
|
||||
return false;
|
||||
}
|
75
rabbit/Class.hpp
Normal file
75
rabbit/Class.hpp
Normal file
@ -0,0 +1,75 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <rabbit/sqpcheader.hpp>
|
||||
#include <rabbit/VirtualMachine.hpp>
|
||||
#include <rabbit/sqtable.hpp>
|
||||
#include <rabbit/sqfuncproto.hpp>
|
||||
#include <rabbit/sqclosure.hpp>
|
||||
#include <rabbit/MetaMethod.hpp>
|
||||
#include <rabbit/ClassMember.hpp>
|
||||
|
||||
namespace rabbit {
|
||||
class Class : public rabbit::RefCounted {
|
||||
public:
|
||||
Class(SQSharedState *ss,rabbit::Class *base);
|
||||
public:
|
||||
static Class* create(SQSharedState *ss, Class *base) {
|
||||
rabbit::Class *newclass = (Class *)SQ_MALLOC(sizeof(Class));
|
||||
new (newclass) Class(ss, base);
|
||||
return newclass;
|
||||
}
|
||||
~Class();
|
||||
bool newSlot(SQSharedState *ss, const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val,bool bstatic);
|
||||
bool get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val) {
|
||||
if(_members->get(key,val)) {
|
||||
if(_isfield(val)) {
|
||||
rabbit::ObjectPtr &o = _defaultvalues[_member_idx(val)].val;
|
||||
val = _realval(o);
|
||||
} else {
|
||||
val = _methods[_member_idx(val)].val;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool getConstructor(rabbit::ObjectPtr &ctor) {
|
||||
if(_constructoridx != -1) {
|
||||
ctor = _methods[_constructoridx].val;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool setAttributes(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val);
|
||||
bool getAttributes(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &outval);
|
||||
void lock() { _locked = true; if(_base) _base->lock(); }
|
||||
void release() {
|
||||
if (_hook) { _hook(_typetag,0);}
|
||||
sq_delete(this, Class);
|
||||
}
|
||||
void finalize();
|
||||
int64_t next(const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey, rabbit::ObjectPtr &outval);
|
||||
rabbit::Instance *createInstance();
|
||||
SQTable *_members;
|
||||
rabbit::Class *_base;
|
||||
etk::Vector<rabbit::ClassMember> _defaultvalues;
|
||||
etk::Vector<rabbit::ClassMember> _methods;
|
||||
rabbit::ObjectPtr _metamethods[rabbit::MT_LAST];
|
||||
rabbit::ObjectPtr _attributes;
|
||||
rabbit::UserPointer _typetag;
|
||||
SQRELEASEHOOK _hook;
|
||||
bool _locked;
|
||||
int64_t _constructoridx;
|
||||
int64_t _udsize;
|
||||
};
|
||||
#define calcinstancesize(_theclass_) \
|
||||
(_theclass_->_udsize + sq_aligning(sizeof(rabbit::Instance) + (sizeof(rabbit::ObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0))))
|
||||
}
|
||||
|
9
rabbit/ClassMember.cpp
Normal file
9
rabbit/ClassMember.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#include <rabbit/ClassMember.hpp>
|
||||
|
37
rabbit/ClassMember.hpp
Normal file
37
rabbit/ClassMember.hpp
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <rabbit/sqconfig.hpp>
|
||||
|
||||
#include <rabbit/ObjectPtr.hpp>
|
||||
|
||||
|
||||
|
||||
#define MEMBER_TYPE_METHOD 0x01000000
|
||||
#define MEMBER_TYPE_FIELD 0x02000000
|
||||
|
||||
#define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD)
|
||||
#define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD)
|
||||
#define _make_method_idx(i) ((int64_t)(MEMBER_TYPE_METHOD|i))
|
||||
#define _make_field_idx(i) ((int64_t)(MEMBER_TYPE_FIELD|i))
|
||||
#define _member_type(o) (_integer(o)&0xFF000000)
|
||||
#define _member_idx(o) (_integer(o)&0x00FFFFFF)
|
||||
|
||||
namespace rabbit {
|
||||
class ClassMember {
|
||||
public:
|
||||
rabbit::ObjectPtr val;
|
||||
rabbit::ObjectPtr attrs;
|
||||
void Null() {
|
||||
val.Null();
|
||||
attrs.Null();
|
||||
}
|
||||
};
|
||||
}
|
66
rabbit/Instance.cpp
Normal file
66
rabbit/Instance.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#include <rabbit/Instance.hpp>
|
||||
|
||||
void rabbit::Instance::init(SQSharedState *ss) {
|
||||
_userpointer = NULL;
|
||||
_hook = NULL;
|
||||
__ObjaddRef(_class);
|
||||
_delegate = _class->_members;
|
||||
}
|
||||
|
||||
rabbit::Instance::Instance(SQSharedState *ss, rabbit::Class *c, int64_t memsize) {
|
||||
_memsize = memsize;
|
||||
_class = c;
|
||||
uint64_t nvalues = _class->_defaultvalues.size();
|
||||
for(uint64_t n = 0; n < nvalues; n++) {
|
||||
new (&_values[n]) rabbit::ObjectPtr(_class->_defaultvalues[n].val);
|
||||
}
|
||||
init(ss);
|
||||
}
|
||||
|
||||
rabbit::Instance::Instance(SQSharedState *ss, rabbit::Instance *i, int64_t memsize) {
|
||||
_memsize = memsize;
|
||||
_class = i->_class;
|
||||
uint64_t nvalues = _class->_defaultvalues.size();
|
||||
for(uint64_t n = 0; n < nvalues; n++) {
|
||||
new (&_values[n]) rabbit::ObjectPtr(i->_values[n]);
|
||||
}
|
||||
init(ss);
|
||||
}
|
||||
|
||||
void rabbit::Instance::finalize() {
|
||||
uint64_t nvalues = _class->_defaultvalues.size();
|
||||
__Objrelease(_class);
|
||||
_NULL_SQOBJECT_VECTOR(_values,nvalues);
|
||||
}
|
||||
|
||||
rabbit::Instance::~Instance() {
|
||||
if(_class){
|
||||
finalize();
|
||||
}
|
||||
}
|
||||
|
||||
bool rabbit::Instance::getMetaMethod(rabbit::VirtualMachine* SQ_UNUSED_ARG(v),rabbit::MetaMethod mm,rabbit::ObjectPtr &res) {
|
||||
if(sq_type(_class->_metamethods[mm]) != rabbit::OT_NULL) {
|
||||
res = _class->_metamethods[mm];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool rabbit::Instance::instanceOf(rabbit::Class *trg) {
|
||||
rabbit::Class *parent = _class;
|
||||
while(parent != NULL) {
|
||||
if(parent == trg) {
|
||||
return true;
|
||||
}
|
||||
parent = parent->_base;
|
||||
}
|
||||
return false;
|
||||
}
|
87
rabbit/Instance.hpp
Normal file
87
rabbit/Instance.hpp
Normal file
@ -0,0 +1,87 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <rabbit/sqpcheader.hpp>
|
||||
#include <rabbit/VirtualMachine.hpp>
|
||||
#include <rabbit/sqtable.hpp>
|
||||
|
||||
#include <rabbit/sqfuncproto.hpp>
|
||||
#include <rabbit/sqclosure.hpp>
|
||||
#include <rabbit/MetaMethod.hpp>
|
||||
|
||||
namespace rabbit {
|
||||
class Instance : public rabbit::Delegable {
|
||||
public:
|
||||
void init(SQSharedState *ss);
|
||||
Instance(SQSharedState *ss, rabbit::Class *c, int64_t memsize);
|
||||
Instance(SQSharedState *ss, Instance *c, int64_t memsize);
|
||||
public:
|
||||
static Instance* create(SQSharedState *ss,rabbit::Class *theclass) {
|
||||
int64_t size = calcinstancesize(theclass);
|
||||
Instance *newinst = (Instance *)SQ_MALLOC(size);
|
||||
new (newinst) Instance(ss, theclass,size);
|
||||
if(theclass->_udsize) {
|
||||
newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize);
|
||||
}
|
||||
return newinst;
|
||||
}
|
||||
Instance *clone(SQSharedState *ss)
|
||||
{
|
||||
int64_t size = calcinstancesize(_class);
|
||||
Instance *newinst = (Instance *)SQ_MALLOC(size);
|
||||
new (newinst) Instance(ss, this,size);
|
||||
if(_class->_udsize) {
|
||||
newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize);
|
||||
}
|
||||
return newinst;
|
||||
}
|
||||
~Instance();
|
||||
bool get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val) {
|
||||
if(_class->_members->get(key,val)) {
|
||||
if(_isfield(val)) {
|
||||
rabbit::ObjectPtr &o = _values[_member_idx(val)];
|
||||
val = _realval(o);
|
||||
}
|
||||
else {
|
||||
val = _class->_methods[_member_idx(val)].val;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool set(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val) {
|
||||
rabbit::ObjectPtr idx;
|
||||
if(_class->_members->get(key,idx) && _isfield(idx)) {
|
||||
_values[_member_idx(idx)] = val;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void release() {
|
||||
_uiRef++;
|
||||
if (_hook) { _hook(_userpointer,0);}
|
||||
_uiRef--;
|
||||
if(_uiRef > 0) return;
|
||||
int64_t size = _memsize;
|
||||
this->~Instance();
|
||||
SQ_FREE(this, size);
|
||||
}
|
||||
void finalize();
|
||||
bool instanceOf(rabbit::Class *trg);
|
||||
bool getMetaMethod(rabbit::VirtualMachine *v,rabbit::MetaMethod mm,rabbit::ObjectPtr &res);
|
||||
|
||||
rabbit::Class *_class;
|
||||
rabbit::UserPointer _userpointer;
|
||||
SQRELEASEHOOK _hook;
|
||||
int64_t _memsize;
|
||||
rabbit::ObjectPtr _values[1];
|
||||
};
|
||||
}
|
||||
|
@ -50,8 +50,8 @@
|
||||
|
||||
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_TABLE, SQTable, pTable)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_CLASS, SQClass, pClass)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_INSTANCE, SQInstance, pInstance)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_CLASS, rabbit::Class, pClass)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_INSTANCE, rabbit::Instance, pInstance)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_ARRAY, rabbit::Array, pArray)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_CLOSURE, SQClosure, pClosure)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_NATIVECLOSURE, SQNativeClosure, pNativeClosure)
|
||||
|
@ -34,8 +34,8 @@ namespace rabbit {
|
||||
ObjectPtr(const Object& _obj);
|
||||
|
||||
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_TABLE, SQTable, pTable)
|
||||
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_CLASS, SQClass, pClass)
|
||||
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_INSTANCE, SQInstance, pInstance)
|
||||
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_CLASS, rabbit::Class, pClass)
|
||||
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_INSTANCE, rabbit::Instance, pInstance)
|
||||
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_ARRAY, rabbit::Array, pArray)
|
||||
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_CLOSURE, SQClosure, pClosure)
|
||||
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_NATIVECLOSURE, SQNativeClosure, pNativeClosure)
|
||||
|
@ -23,9 +23,9 @@ namespace rabbit {
|
||||
int64_t nInteger;
|
||||
float_t fFloat;
|
||||
struct SQFunctionProto *pFunctionProto;
|
||||
struct SQClass *pClass;
|
||||
struct SQInstance *pInstance;
|
||||
|
||||
rabbit::Class *pClass;
|
||||
rabbit::Instance *pInstance;
|
||||
rabbit::Delegable *pDelegable;
|
||||
rabbit::UserPointer pUserPointer;
|
||||
rabbit::WeakRef* pWeakRef;
|
||||
|
@ -16,7 +16,8 @@
|
||||
#include <rabbit/sqtable.hpp>
|
||||
#include <rabbit/UserData.hpp>
|
||||
#include <rabbit/Array.hpp>
|
||||
#include <rabbit/sqclass.hpp>
|
||||
#include <rabbit/Instance.hpp>
|
||||
|
||||
|
||||
#define TOP() (_stack[_top-1])
|
||||
#define TARGET _stack[_stackbase+arg0]
|
||||
@ -616,7 +617,7 @@ bool rabbit::VirtualMachine::CLOSURE_OP(rabbit::ObjectPtr &target, SQFunctionPro
|
||||
|
||||
bool rabbit::VirtualMachine::CLASS_OP(rabbit::ObjectPtr &target,int64_t baseclass,int64_t attributes)
|
||||
{
|
||||
SQClass *base = NULL;
|
||||
rabbit::Class *base = NULL;
|
||||
rabbit::ObjectPtr attrs;
|
||||
if(baseclass != -1) {
|
||||
if(sq_type(_stack[_stackbase+baseclass]) != rabbit::OT_CLASS) { raise_error(_SC("trying to inherit from a %s"),getTypeName(_stack[_stackbase+baseclass])); return false; }
|
||||
@ -625,7 +626,7 @@ bool rabbit::VirtualMachine::CLASS_OP(rabbit::ObjectPtr &target,int64_t baseclas
|
||||
if(attributes != MAX_FUNC_STACKSIZE) {
|
||||
attrs = _stack[_stackbase+attributes];
|
||||
}
|
||||
target = SQClass::create(_get_shared_state(this),base);
|
||||
target = rabbit::Class::create(_get_shared_state(this),base);
|
||||
if(sq_type(_class(target)->_metamethods[MT_INHERITED]) != rabbit::OT_NULL) {
|
||||
int nparams = 2;
|
||||
rabbit::ObjectPtr ret;
|
||||
@ -1103,7 +1104,7 @@ exception_trap:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
bool rabbit::VirtualMachine::createClassInstance(SQClass *theclass, rabbit::ObjectPtr &inst, rabbit::ObjectPtr &constructor)
|
||||
bool rabbit::VirtualMachine::createClassInstance(rabbit::Class *theclass, rabbit::ObjectPtr &inst, rabbit::ObjectPtr &constructor)
|
||||
{
|
||||
inst = theclass->createInstance();
|
||||
if(!theclass->getConstructor(constructor)) {
|
||||
@ -1455,7 +1456,7 @@ bool rabbit::VirtualMachine::newSlotA(const rabbit::ObjectPtr &self,const rabbit
|
||||
raise_error(_SC("object must be a class"));
|
||||
return false;
|
||||
}
|
||||
SQClass *c = _class(self);
|
||||
rabbit::Class *c = _class(self);
|
||||
if(!raw) {
|
||||
rabbit::ObjectPtr &mm = c->_metamethods[MT_NEWMEMBER];
|
||||
if(sq_type(mm) != rabbit::OT_NULL ) {
|
||||
|
@ -67,7 +67,7 @@ namespace rabbit {
|
||||
bool tailcall(SQClosure *closure, int64_t firstparam, int64_t nparams);
|
||||
//starts a RABBIT call in the same "Execution loop"
|
||||
bool startcall(SQClosure *closure, int64_t target, int64_t nargs, int64_t stackbase, bool tailcall);
|
||||
bool createClassInstance(SQClass *theclass, rabbit::ObjectPtr &inst, rabbit::ObjectPtr &constructor);
|
||||
bool createClassInstance(rabbit::Class *theclass, rabbit::ObjectPtr &inst, rabbit::ObjectPtr &constructor);
|
||||
//call a generic closure pure RABBIT or NATIVE
|
||||
bool call(rabbit::ObjectPtr &closure, int64_t nparams, int64_t stackbase, rabbit::ObjectPtr &outres,rabbit::Bool raiseerror);
|
||||
rabbit::Result Suspend();
|
||||
|
@ -15,7 +15,8 @@
|
||||
#include <rabbit/UserData.hpp>
|
||||
#include <rabbit/sqcompiler.hpp>
|
||||
#include <rabbit/sqfuncstate.hpp>
|
||||
#include <rabbit/sqclass.hpp>
|
||||
#include <rabbit/Instance.hpp>
|
||||
|
||||
#include <rabbit/MemberHandle.hpp>
|
||||
|
||||
static bool sq_aux_gettypedarg(rabbit::VirtualMachine* v,int64_t idx,rabbit::ObjectType type,rabbit::ObjectPtr **o)
|
||||
@ -283,14 +284,14 @@ void sq_newarray(rabbit::VirtualMachine* v,int64_t size)
|
||||
|
||||
rabbit::Result sq_newclass(rabbit::VirtualMachine* v,rabbit::Bool hasbase)
|
||||
{
|
||||
SQClass *baseclass = NULL;
|
||||
rabbit::Class *baseclass = NULL;
|
||||
if(hasbase) {
|
||||
rabbit::ObjectPtr &base = stack_get(v,-1);
|
||||
if(sq_type(base) != rabbit::OT_CLASS)
|
||||
return sq_throwerror(v,_SC("invalid base type"));
|
||||
baseclass = _class(base);
|
||||
}
|
||||
SQClass *newclass = SQClass::create(_get_shared_state(v), baseclass);
|
||||
rabbit::Class *newclass = rabbit::Class::create(_get_shared_state(v), baseclass);
|
||||
if(baseclass) v->pop();
|
||||
v->push(newclass);
|
||||
return SQ_OK;
|
||||
@ -820,7 +821,7 @@ rabbit::Result sq_getinstanceup(rabbit::VirtualMachine* v, int64_t idx, rabbit::
|
||||
if(sq_type(o) != rabbit::OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));
|
||||
(*p) = _instance(o)->_userpointer;
|
||||
if(typetag != 0) {
|
||||
SQClass *cl = _instance(o)->_class;
|
||||
rabbit::Class *cl = _instance(o)->_class;
|
||||
do{
|
||||
if(cl->_typetag == typetag)
|
||||
return SQ_OK;
|
||||
@ -1460,9 +1461,9 @@ rabbit::Result _getmemberbyhandle(rabbit::VirtualMachine* v,rabbit::ObjectPtr &s
|
||||
{
|
||||
switch(sq_type(self)) {
|
||||
case rabbit::OT_INSTANCE: {
|
||||
SQInstance *i = _instance(self);
|
||||
rabbit::Instance *i = _instance(self);
|
||||
if(handle->_static) {
|
||||
SQClass *c = i->_class;
|
||||
rabbit::Class *c = i->_class;
|
||||
val = &c->_methods[handle->_index].val;
|
||||
}
|
||||
else {
|
||||
@ -1472,7 +1473,7 @@ rabbit::Result _getmemberbyhandle(rabbit::VirtualMachine* v,rabbit::ObjectPtr &s
|
||||
}
|
||||
break;
|
||||
case rabbit::OT_CLASS: {
|
||||
SQClass *c = _class(self);
|
||||
rabbit::Class *c = _class(self);
|
||||
if(handle->_static) {
|
||||
val = &c->_methods[handle->_index].val;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <rabbit/Array.hpp>
|
||||
#include <rabbit/sqfuncproto.hpp>
|
||||
#include <rabbit/sqclosure.hpp>
|
||||
#include <rabbit/sqclass.hpp>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
@ -1,158 +0,0 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
struct SQInstance;
|
||||
|
||||
struct SQClassMember {
|
||||
rabbit::ObjectPtr val;
|
||||
rabbit::ObjectPtr attrs;
|
||||
void Null() {
|
||||
val.Null();
|
||||
attrs.Null();
|
||||
}
|
||||
};
|
||||
|
||||
typedef etk::Vector<SQClassMember> SQClassMemberVec;
|
||||
|
||||
#define MEMBER_TYPE_METHOD 0x01000000
|
||||
#define MEMBER_TYPE_FIELD 0x02000000
|
||||
|
||||
#define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD)
|
||||
#define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD)
|
||||
#define _make_method_idx(i) ((int64_t)(MEMBER_TYPE_METHOD|i))
|
||||
#define _make_field_idx(i) ((int64_t)(MEMBER_TYPE_FIELD|i))
|
||||
#define _member_type(o) (_integer(o)&0xFF000000)
|
||||
#define _member_idx(o) (_integer(o)&0x00FFFFFF)
|
||||
|
||||
struct SQClass : public rabbit::RefCounted
|
||||
{
|
||||
SQClass(SQSharedState *ss,SQClass *base);
|
||||
public:
|
||||
static SQClass* create(SQSharedState *ss,SQClass *base) {
|
||||
SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass));
|
||||
new (newclass) SQClass(ss, base);
|
||||
return newclass;
|
||||
}
|
||||
~SQClass();
|
||||
bool newSlot(SQSharedState *ss, const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val,bool bstatic);
|
||||
bool get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val) {
|
||||
if(_members->get(key,val)) {
|
||||
if(_isfield(val)) {
|
||||
rabbit::ObjectPtr &o = _defaultvalues[_member_idx(val)].val;
|
||||
val = _realval(o);
|
||||
}
|
||||
else {
|
||||
val = _methods[_member_idx(val)].val;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool getConstructor(rabbit::ObjectPtr &ctor)
|
||||
{
|
||||
if(_constructoridx != -1) {
|
||||
ctor = _methods[_constructoridx].val;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool setAttributes(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val);
|
||||
bool getAttributes(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &outval);
|
||||
void lock() { _locked = true; if(_base) _base->lock(); }
|
||||
void release() {
|
||||
if (_hook) { _hook(_typetag,0);}
|
||||
sq_delete(this, SQClass);
|
||||
}
|
||||
void finalize();
|
||||
int64_t next(const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey, rabbit::ObjectPtr &outval);
|
||||
SQInstance *createInstance();
|
||||
SQTable *_members;
|
||||
SQClass *_base;
|
||||
SQClassMemberVec _defaultvalues;
|
||||
SQClassMemberVec _methods;
|
||||
rabbit::ObjectPtr _metamethods[rabbit::MT_LAST];
|
||||
rabbit::ObjectPtr _attributes;
|
||||
rabbit::UserPointer _typetag;
|
||||
SQRELEASEHOOK _hook;
|
||||
bool _locked;
|
||||
int64_t _constructoridx;
|
||||
int64_t _udsize;
|
||||
};
|
||||
|
||||
#define calcinstancesize(_theclass_) \
|
||||
(_theclass_->_udsize + sq_aligning(sizeof(SQInstance) + (sizeof(rabbit::ObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0))))
|
||||
|
||||
struct SQInstance : public rabbit::Delegable
|
||||
{
|
||||
void init(SQSharedState *ss);
|
||||
SQInstance(SQSharedState *ss, SQClass *c, int64_t memsize);
|
||||
SQInstance(SQSharedState *ss, SQInstance *c, int64_t memsize);
|
||||
public:
|
||||
static SQInstance* create(SQSharedState *ss,SQClass *theclass) {
|
||||
|
||||
int64_t size = calcinstancesize(theclass);
|
||||
SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
|
||||
new (newinst) SQInstance(ss, theclass,size);
|
||||
if(theclass->_udsize) {
|
||||
newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize);
|
||||
}
|
||||
return newinst;
|
||||
}
|
||||
SQInstance *clone(SQSharedState *ss)
|
||||
{
|
||||
int64_t size = calcinstancesize(_class);
|
||||
SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
|
||||
new (newinst) SQInstance(ss, this,size);
|
||||
if(_class->_udsize) {
|
||||
newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize);
|
||||
}
|
||||
return newinst;
|
||||
}
|
||||
~SQInstance();
|
||||
bool get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val) {
|
||||
if(_class->_members->get(key,val)) {
|
||||
if(_isfield(val)) {
|
||||
rabbit::ObjectPtr &o = _values[_member_idx(val)];
|
||||
val = _realval(o);
|
||||
}
|
||||
else {
|
||||
val = _class->_methods[_member_idx(val)].val;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool set(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val) {
|
||||
rabbit::ObjectPtr idx;
|
||||
if(_class->_members->get(key,idx) && _isfield(idx)) {
|
||||
_values[_member_idx(idx)] = val;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void release() {
|
||||
_uiRef++;
|
||||
if (_hook) { _hook(_userpointer,0);}
|
||||
_uiRef--;
|
||||
if(_uiRef > 0) return;
|
||||
int64_t size = _memsize;
|
||||
this->~SQInstance();
|
||||
SQ_FREE(this, size);
|
||||
}
|
||||
void finalize();
|
||||
bool instanceOf(SQClass *trg);
|
||||
bool getMetaMethod(rabbit::VirtualMachine *v,rabbit::MetaMethod mm,rabbit::ObjectPtr &res);
|
||||
|
||||
SQClass *_class;
|
||||
rabbit::UserPointer _userpointer;
|
||||
SQRELEASEHOOK _hook;
|
||||
int64_t _memsize;
|
||||
rabbit::ObjectPtr _values[1];
|
||||
};
|
||||
|
@ -7,10 +7,12 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <rabbit/Class.hpp>
|
||||
#include <rabbit/sqconfig.hpp>
|
||||
|
||||
#define _CALC_CLOSURE_SIZE(func) (sizeof(SQClosure) + (func->_noutervalues*sizeof(rabbit::ObjectPtr)) + (func->_ndefaultparams*sizeof(rabbit::ObjectPtr)))
|
||||
|
||||
struct SQFunctionProto;
|
||||
struct SQClass;
|
||||
struct SQClosure : public rabbit::RefCounted
|
||||
{
|
||||
private:
|
||||
@ -64,7 +66,7 @@ public:
|
||||
static bool load(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQREADFUNC read,rabbit::ObjectPtr &ret);
|
||||
rabbit::WeakRef *_env;
|
||||
rabbit::WeakRef *_root;
|
||||
SQClass *_base;
|
||||
rabbit::Class *_base;
|
||||
SQFunctionProto *_function;
|
||||
rabbit::ObjectPtr *_outervalues;
|
||||
rabbit::ObjectPtr *_defaultparams;
|
||||
|
@ -131,8 +131,6 @@ struct SQClosure;
|
||||
struct SQGenerator;
|
||||
struct SQNativeClosure;
|
||||
struct SQFunctionProto;
|
||||
struct SQClass;
|
||||
struct SQInstance;
|
||||
struct SQOuter;
|
||||
struct SQSharedState;
|
||||
namespace rabbit {
|
||||
@ -145,4 +143,6 @@ namespace rabbit {
|
||||
class FunctionInfo;
|
||||
class StackInfos;
|
||||
class MemberHandle;
|
||||
class Instance;
|
||||
class Class;
|
||||
}
|
@ -12,7 +12,7 @@
|
||||
#include <rabbit/sqtable.hpp>
|
||||
#include <rabbit/UserData.hpp>
|
||||
#include <rabbit/sqfuncproto.hpp>
|
||||
#include <rabbit/sqclass.hpp>
|
||||
|
||||
#include <rabbit/sqclosure.hpp>
|
||||
|
||||
SQString *SQString::create(SQSharedState *ss,const rabbit::Char *s,int64_t len)
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <rabbit/sqtable.hpp>
|
||||
#include <rabbit/Array.hpp>
|
||||
#include <rabbit/UserData.hpp>
|
||||
#include <rabbit/sqclass.hpp>
|
||||
|
||||
|
||||
SQSharedState::SQSharedState()
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user