[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/sqbaselib.cpp',
|
||||||
'rabbit/sqapi.cpp',
|
'rabbit/sqapi.cpp',
|
||||||
'rabbit/sqlexer.cpp',
|
'rabbit/sqlexer.cpp',
|
||||||
'rabbit/sqclass.cpp',
|
'rabbit/Class.cpp',
|
||||||
|
'rabbit/ClassMember.cpp',
|
||||||
|
'rabbit/Instance.cpp',
|
||||||
'rabbit/AutoDec.cpp',
|
'rabbit/AutoDec.cpp',
|
||||||
'rabbit/VirtualMachine.cpp',
|
'rabbit/VirtualMachine.cpp',
|
||||||
'rabbit/sqtable.cpp',
|
'rabbit/sqtable.cpp',
|
||||||
@ -62,7 +64,9 @@ def configure(target, my_module):
|
|||||||
'etk-base',
|
'etk-base',
|
||||||
])
|
])
|
||||||
my_module.add_header_file([
|
my_module.add_header_file([
|
||||||
'rabbit/sqclass.hpp',
|
'rabbit/Class.hpp',
|
||||||
|
'rabbit/ClassMember.hpp',
|
||||||
|
'rabbit/Instance.hpp',
|
||||||
'rabbit/AutoDec.hpp',
|
'rabbit/AutoDec.hpp',
|
||||||
'rabbit/VirtualMachine.hpp',
|
'rabbit/VirtualMachine.hpp',
|
||||||
'rabbit/sqstate.hpp',
|
'rabbit/sqstate.hpp',
|
||||||
|
@ -5,17 +5,11 @@
|
|||||||
* @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)
|
||||||
*/
|
*/
|
||||||
#include <rabbit/sqpcheader.hpp>
|
#include <rabbit/Class.hpp>
|
||||||
#include <rabbit/VirtualMachine.hpp>
|
#include <rabbit/Instance.hpp>
|
||||||
#include <rabbit/sqtable.hpp>
|
|
||||||
#include <rabbit/sqclass.hpp>
|
|
||||||
#include <rabbit/sqfuncproto.hpp>
|
|
||||||
#include <rabbit/sqclosure.hpp>
|
|
||||||
#include <rabbit/MetaMethod.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
SQClass::SQClass(SQSharedState *ss,SQClass *base)
|
rabbit::Class::Class(SQSharedState *ss,rabbit::Class *base) {
|
||||||
{
|
|
||||||
_base = base;
|
_base = base;
|
||||||
_typetag = 0;
|
_typetag = 0;
|
||||||
_hook = NULL;
|
_hook = NULL;
|
||||||
@ -34,7 +28,7 @@ SQClass::SQClass(SQSharedState *ss,SQClass *base)
|
|||||||
__ObjaddRef(_members);
|
__ObjaddRef(_members);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SQClass::finalize() {
|
void rabbit::Class::finalize() {
|
||||||
_attributes.Null();
|
_attributes.Null();
|
||||||
_NULL_SQOBJECT_VECTOR(_defaultvalues,_defaultvalues.size());
|
_NULL_SQOBJECT_VECTOR(_defaultvalues,_defaultvalues.size());
|
||||||
_methods.resize(0);
|
_methods.resize(0);
|
||||||
@ -45,21 +39,21 @@ void SQClass::finalize() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SQClass::~SQClass()
|
rabbit::Class::~Class() {
|
||||||
{
|
|
||||||
finalize();
|
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;
|
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
|
||||||
|| bstatic;
|
|| bstatic;
|
||||||
if(_locked && !belongs_to_static_table)
|
if(_locked && !belongs_to_static_table) {
|
||||||
return false; //the class already has an instance so cannot be modified
|
//the class already has an instance so cannot be modified
|
||||||
if(_members->get(key,temp) && _isfield(temp)) //overrides the default value
|
return false;
|
||||||
{
|
}
|
||||||
|
//overrides the default value
|
||||||
|
if(_members->get(key,temp) && _isfield(temp)) {
|
||||||
_defaultvalues[_member_idx(temp)].val = val;
|
_defaultvalues[_member_idx(temp)].val = val;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -69,8 +63,7 @@ bool SQClass::newSlot(SQSharedState *ss,const rabbit::ObjectPtr &key,const rabbi
|
|||||||
|| sq_type(val) == rabbit::OT_NATIVECLOSURE )
|
|| sq_type(val) == rabbit::OT_NATIVECLOSURE )
|
||||||
&& (mmidx = ss->getMetaMethodIdxByName(key)) != -1) {
|
&& (mmidx = ss->getMetaMethodIdxByName(key)) != -1) {
|
||||||
_metamethods[mmidx] = val;
|
_metamethods[mmidx] = val;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
rabbit::ObjectPtr theval = val;
|
rabbit::ObjectPtr theval = val;
|
||||||
if(_base && sq_type(val) == rabbit::OT_CLOSURE) {
|
if(_base && sq_type(val) == rabbit::OT_CLOSURE) {
|
||||||
theval = _closure(val)->clone();
|
theval = _closure(val)->clone();
|
||||||
@ -83,39 +76,37 @@ bool SQClass::newSlot(SQSharedState *ss,const rabbit::ObjectPtr &key,const rabbi
|
|||||||
if(isconstructor) {
|
if(isconstructor) {
|
||||||
_constructoridx = (int64_t)_methods.size();
|
_constructoridx = (int64_t)_methods.size();
|
||||||
}
|
}
|
||||||
SQClassMember m;
|
rabbit::ClassMember m;
|
||||||
m.val = theval;
|
m.val = theval;
|
||||||
_members->newSlot(key,rabbit::ObjectPtr(_make_method_idx(_methods.size())));
|
_members->newSlot(key,rabbit::ObjectPtr(_make_method_idx(_methods.size())));
|
||||||
_methods.pushBack(m);
|
_methods.pushBack(m);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
_methods[_member_idx(temp)].val = theval;
|
_methods[_member_idx(temp)].val = theval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
SQClassMember m;
|
rabbit::ClassMember m;
|
||||||
m.val = val;
|
m.val = val;
|
||||||
_members->newSlot(key,rabbit::ObjectPtr(_make_field_idx(_defaultvalues.size())));
|
_members->newSlot(key,rabbit::ObjectPtr(_make_field_idx(_defaultvalues.size())));
|
||||||
_defaultvalues.pushBack(m);
|
_defaultvalues.pushBack(m);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SQInstance *SQClass::createInstance()
|
rabbit::Instance *rabbit::Class::createInstance() {
|
||||||
{
|
if(!_locked) {
|
||||||
if(!_locked) lock();
|
lock();
|
||||||
return SQInstance::create(NULL,this);
|
}
|
||||||
|
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;
|
rabbit::ObjectPtr oval;
|
||||||
int64_t idx = _members->next(false,refpos,outkey,oval);
|
int64_t idx = _members->next(false,refpos,outkey,oval);
|
||||||
if(idx != -1) {
|
if(idx != -1) {
|
||||||
if(_ismethod(oval)) {
|
if(_ismethod(oval)) {
|
||||||
outval = _methods[_member_idx(oval)].val;
|
outval = _methods[_member_idx(oval)].val;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
rabbit::ObjectPtr &o = _defaultvalues[_member_idx(oval)].val;
|
rabbit::ObjectPtr &o = _defaultvalues[_member_idx(oval)].val;
|
||||||
outval = _realval(o);
|
outval = _realval(o);
|
||||||
}
|
}
|
||||||
@ -123,21 +114,20 @@ int64_t SQClass::next(const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey
|
|||||||
return idx;
|
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;
|
rabbit::ObjectPtr idx;
|
||||||
if(_members->get(key,idx)) {
|
if(_members->get(key,idx)) {
|
||||||
if(_isfield(idx))
|
if(_isfield(idx)) {
|
||||||
_defaultvalues[_member_idx(idx)].attrs = val;
|
_defaultvalues[_member_idx(idx)].attrs = val;
|
||||||
else
|
} else {
|
||||||
_methods[_member_idx(idx)].attrs = val;
|
_methods[_member_idx(idx)].attrs = val;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
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;
|
rabbit::ObjectPtr idx;
|
||||||
if(_members->get(key,idx)) {
|
if(_members->get(key,idx)) {
|
||||||
outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs);
|
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;
|
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_TABLE, SQTable, pTable)
|
||||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_CLASS, SQClass, pClass)
|
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_CLASS, rabbit::Class, pClass)
|
||||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_INSTANCE, SQInstance, 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)
|
||||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_CLOSURE, SQClosure, pClosure)
|
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)
|
||||||
|
@ -34,8 +34,8 @@ namespace rabbit {
|
|||||||
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, SQTable, pTable)
|
||||||
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_CLASS, SQClass, pClass)
|
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_CLASS, rabbit::Class, pClass)
|
||||||
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_INSTANCE, SQInstance, 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)
|
||||||
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_CLOSURE, SQClosure, pClosure)
|
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_CLOSURE, SQClosure, pClosure)
|
||||||
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_NATIVECLOSURE, SQNativeClosure, pNativeClosure)
|
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_NATIVECLOSURE, SQNativeClosure, pNativeClosure)
|
||||||
|
@ -23,9 +23,9 @@ namespace rabbit {
|
|||||||
int64_t nInteger;
|
int64_t nInteger;
|
||||||
float_t fFloat;
|
float_t fFloat;
|
||||||
struct SQFunctionProto *pFunctionProto;
|
struct SQFunctionProto *pFunctionProto;
|
||||||
struct SQClass *pClass;
|
|
||||||
struct SQInstance *pInstance;
|
|
||||||
|
|
||||||
|
rabbit::Class *pClass;
|
||||||
|
rabbit::Instance *pInstance;
|
||||||
rabbit::Delegable *pDelegable;
|
rabbit::Delegable *pDelegable;
|
||||||
rabbit::UserPointer pUserPointer;
|
rabbit::UserPointer pUserPointer;
|
||||||
rabbit::WeakRef* pWeakRef;
|
rabbit::WeakRef* pWeakRef;
|
||||||
|
@ -16,7 +16,8 @@
|
|||||||
#include <rabbit/sqtable.hpp>
|
#include <rabbit/sqtable.hpp>
|
||||||
#include <rabbit/UserData.hpp>
|
#include <rabbit/UserData.hpp>
|
||||||
#include <rabbit/Array.hpp>
|
#include <rabbit/Array.hpp>
|
||||||
#include <rabbit/sqclass.hpp>
|
#include <rabbit/Instance.hpp>
|
||||||
|
|
||||||
|
|
||||||
#define TOP() (_stack[_top-1])
|
#define TOP() (_stack[_top-1])
|
||||||
#define TARGET _stack[_stackbase+arg0]
|
#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)
|
bool rabbit::VirtualMachine::CLASS_OP(rabbit::ObjectPtr &target,int64_t baseclass,int64_t attributes)
|
||||||
{
|
{
|
||||||
SQClass *base = NULL;
|
rabbit::Class *base = NULL;
|
||||||
rabbit::ObjectPtr attrs;
|
rabbit::ObjectPtr attrs;
|
||||||
if(baseclass != -1) {
|
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; }
|
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) {
|
if(attributes != MAX_FUNC_STACKSIZE) {
|
||||||
attrs = _stack[_stackbase+attributes];
|
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) {
|
if(sq_type(_class(target)->_metamethods[MT_INHERITED]) != rabbit::OT_NULL) {
|
||||||
int nparams = 2;
|
int nparams = 2;
|
||||||
rabbit::ObjectPtr ret;
|
rabbit::ObjectPtr ret;
|
||||||
@ -1103,7 +1104,7 @@ exception_trap:
|
|||||||
assert(0);
|
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();
|
inst = theclass->createInstance();
|
||||||
if(!theclass->getConstructor(constructor)) {
|
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"));
|
raise_error(_SC("object must be a class"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
SQClass *c = _class(self);
|
rabbit::Class *c = _class(self);
|
||||||
if(!raw) {
|
if(!raw) {
|
||||||
rabbit::ObjectPtr &mm = c->_metamethods[MT_NEWMEMBER];
|
rabbit::ObjectPtr &mm = c->_metamethods[MT_NEWMEMBER];
|
||||||
if(sq_type(mm) != rabbit::OT_NULL ) {
|
if(sq_type(mm) != rabbit::OT_NULL ) {
|
||||||
|
@ -67,7 +67,7 @@ namespace rabbit {
|
|||||||
bool tailcall(SQClosure *closure, int64_t firstparam, int64_t nparams);
|
bool tailcall(SQClosure *closure, int64_t firstparam, int64_t nparams);
|
||||||
//starts a RABBIT call in the same "Execution loop"
|
//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 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
|
//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);
|
bool call(rabbit::ObjectPtr &closure, int64_t nparams, int64_t stackbase, rabbit::ObjectPtr &outres,rabbit::Bool raiseerror);
|
||||||
rabbit::Result Suspend();
|
rabbit::Result Suspend();
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
#include <rabbit/UserData.hpp>
|
#include <rabbit/UserData.hpp>
|
||||||
#include <rabbit/sqcompiler.hpp>
|
#include <rabbit/sqcompiler.hpp>
|
||||||
#include <rabbit/sqfuncstate.hpp>
|
#include <rabbit/sqfuncstate.hpp>
|
||||||
#include <rabbit/sqclass.hpp>
|
#include <rabbit/Instance.hpp>
|
||||||
|
|
||||||
#include <rabbit/MemberHandle.hpp>
|
#include <rabbit/MemberHandle.hpp>
|
||||||
|
|
||||||
static bool sq_aux_gettypedarg(rabbit::VirtualMachine* v,int64_t idx,rabbit::ObjectType type,rabbit::ObjectPtr **o)
|
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)
|
rabbit::Result sq_newclass(rabbit::VirtualMachine* v,rabbit::Bool hasbase)
|
||||||
{
|
{
|
||||||
SQClass *baseclass = NULL;
|
rabbit::Class *baseclass = NULL;
|
||||||
if(hasbase) {
|
if(hasbase) {
|
||||||
rabbit::ObjectPtr &base = stack_get(v,-1);
|
rabbit::ObjectPtr &base = stack_get(v,-1);
|
||||||
if(sq_type(base) != rabbit::OT_CLASS)
|
if(sq_type(base) != rabbit::OT_CLASS)
|
||||||
return sq_throwerror(v,_SC("invalid base type"));
|
return sq_throwerror(v,_SC("invalid base type"));
|
||||||
baseclass = _class(base);
|
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();
|
if(baseclass) v->pop();
|
||||||
v->push(newclass);
|
v->push(newclass);
|
||||||
return SQ_OK;
|
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"));
|
if(sq_type(o) != rabbit::OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));
|
||||||
(*p) = _instance(o)->_userpointer;
|
(*p) = _instance(o)->_userpointer;
|
||||||
if(typetag != 0) {
|
if(typetag != 0) {
|
||||||
SQClass *cl = _instance(o)->_class;
|
rabbit::Class *cl = _instance(o)->_class;
|
||||||
do{
|
do{
|
||||||
if(cl->_typetag == typetag)
|
if(cl->_typetag == typetag)
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
@ -1460,9 +1461,9 @@ rabbit::Result _getmemberbyhandle(rabbit::VirtualMachine* v,rabbit::ObjectPtr &s
|
|||||||
{
|
{
|
||||||
switch(sq_type(self)) {
|
switch(sq_type(self)) {
|
||||||
case rabbit::OT_INSTANCE: {
|
case rabbit::OT_INSTANCE: {
|
||||||
SQInstance *i = _instance(self);
|
rabbit::Instance *i = _instance(self);
|
||||||
if(handle->_static) {
|
if(handle->_static) {
|
||||||
SQClass *c = i->_class;
|
rabbit::Class *c = i->_class;
|
||||||
val = &c->_methods[handle->_index].val;
|
val = &c->_methods[handle->_index].val;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1472,7 +1473,7 @@ rabbit::Result _getmemberbyhandle(rabbit::VirtualMachine* v,rabbit::ObjectPtr &s
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case rabbit::OT_CLASS: {
|
case rabbit::OT_CLASS: {
|
||||||
SQClass *c = _class(self);
|
rabbit::Class *c = _class(self);
|
||||||
if(handle->_static) {
|
if(handle->_static) {
|
||||||
val = &c->_methods[handle->_index].val;
|
val = &c->_methods[handle->_index].val;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include <rabbit/Array.hpp>
|
#include <rabbit/Array.hpp>
|
||||||
#include <rabbit/sqfuncproto.hpp>
|
#include <rabbit/sqfuncproto.hpp>
|
||||||
#include <rabbit/sqclosure.hpp>
|
#include <rabbit/sqclosure.hpp>
|
||||||
#include <rabbit/sqclass.hpp>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <ctype.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
|
#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)))
|
#define _CALC_CLOSURE_SIZE(func) (sizeof(SQClosure) + (func->_noutervalues*sizeof(rabbit::ObjectPtr)) + (func->_ndefaultparams*sizeof(rabbit::ObjectPtr)))
|
||||||
|
|
||||||
struct SQFunctionProto;
|
struct SQFunctionProto;
|
||||||
struct SQClass;
|
|
||||||
struct SQClosure : public rabbit::RefCounted
|
struct SQClosure : public rabbit::RefCounted
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@ -64,7 +66,7 @@ public:
|
|||||||
static bool load(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQREADFUNC read,rabbit::ObjectPtr &ret);
|
static bool load(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQREADFUNC read,rabbit::ObjectPtr &ret);
|
||||||
rabbit::WeakRef *_env;
|
rabbit::WeakRef *_env;
|
||||||
rabbit::WeakRef *_root;
|
rabbit::WeakRef *_root;
|
||||||
SQClass *_base;
|
rabbit::Class *_base;
|
||||||
SQFunctionProto *_function;
|
SQFunctionProto *_function;
|
||||||
rabbit::ObjectPtr *_outervalues;
|
rabbit::ObjectPtr *_outervalues;
|
||||||
rabbit::ObjectPtr *_defaultparams;
|
rabbit::ObjectPtr *_defaultparams;
|
||||||
|
@ -131,8 +131,6 @@ struct SQClosure;
|
|||||||
struct SQGenerator;
|
struct SQGenerator;
|
||||||
struct SQNativeClosure;
|
struct SQNativeClosure;
|
||||||
struct SQFunctionProto;
|
struct SQFunctionProto;
|
||||||
struct SQClass;
|
|
||||||
struct SQInstance;
|
|
||||||
struct SQOuter;
|
struct SQOuter;
|
||||||
struct SQSharedState;
|
struct SQSharedState;
|
||||||
namespace rabbit {
|
namespace rabbit {
|
||||||
@ -145,4 +143,6 @@ namespace rabbit {
|
|||||||
class FunctionInfo;
|
class FunctionInfo;
|
||||||
class StackInfos;
|
class StackInfos;
|
||||||
class MemberHandle;
|
class MemberHandle;
|
||||||
|
class Instance;
|
||||||
|
class Class;
|
||||||
}
|
}
|
@ -12,7 +12,7 @@
|
|||||||
#include <rabbit/sqtable.hpp>
|
#include <rabbit/sqtable.hpp>
|
||||||
#include <rabbit/UserData.hpp>
|
#include <rabbit/UserData.hpp>
|
||||||
#include <rabbit/sqfuncproto.hpp>
|
#include <rabbit/sqfuncproto.hpp>
|
||||||
#include <rabbit/sqclass.hpp>
|
|
||||||
#include <rabbit/sqclosure.hpp>
|
#include <rabbit/sqclosure.hpp>
|
||||||
|
|
||||||
SQString *SQString::create(SQSharedState *ss,const rabbit::Char *s,int64_t len)
|
SQString *SQString::create(SQSharedState *ss,const rabbit::Char *s,int64_t len)
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#include <rabbit/sqtable.hpp>
|
#include <rabbit/sqtable.hpp>
|
||||||
#include <rabbit/Array.hpp>
|
#include <rabbit/Array.hpp>
|
||||||
#include <rabbit/UserData.hpp>
|
#include <rabbit/UserData.hpp>
|
||||||
#include <rabbit/sqclass.hpp>
|
|
||||||
|
|
||||||
SQSharedState::SQSharedState()
|
SQSharedState::SQSharedState()
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user