[DEV] continue rework (main step)
This commit is contained in:
parent
45e2df01f0
commit
aa49dbd05d
@ -27,85 +27,110 @@ def get_version():
|
||||
|
||||
def configure(target, my_module):
|
||||
my_module.add_src_file([
|
||||
'rabbit/Hash.cpp',
|
||||
'rabbit/RefTable.cpp',
|
||||
'rabbit/SharedState.cpp',
|
||||
'rabbit/String.cpp',
|
||||
'rabbit/StringTable.cpp',
|
||||
'rabbit/Table.cpp',
|
||||
'rabbit/sqmem.cpp',
|
||||
'rabbit/sqbaselib.cpp',
|
||||
'rabbit/sqapi.cpp',
|
||||
'rabbit/sqlexer.cpp',
|
||||
'rabbit/Class.cpp',
|
||||
'rabbit/ClassMember.cpp',
|
||||
'rabbit/Instance.cpp',
|
||||
'rabbit/AutoDec.cpp',
|
||||
'rabbit/VirtualMachine.cpp',
|
||||
'rabbit/sqobject.cpp',
|
||||
'rabbit/sqcompiler.cpp',
|
||||
'rabbit/sqdebug.cpp',
|
||||
'rabbit/sqfuncstate.cpp',
|
||||
'rabbit/RefCounted.cpp',
|
||||
'rabbit/WeakRef.cpp',
|
||||
'rabbit/Delegable.cpp',
|
||||
'rabbit/ObjectType.cpp',
|
||||
'rabbit/ObjectValue.cpp',
|
||||
'rabbit/Object.cpp',
|
||||
'rabbit/ObjectPtr.cpp',
|
||||
'rabbit/MemberHandle.cpp',
|
||||
'rabbit/StackInfos.cpp',
|
||||
'rabbit/RegFunction.cpp',
|
||||
'rabbit/FunctionInfo.cpp',
|
||||
'rabbit/MetaMethod.cpp',
|
||||
'rabbit/ExceptionTrap.cpp',
|
||||
])
|
||||
'rabbit/Array.cpp',
|
||||
'rabbit/AutoDec.cpp',
|
||||
'rabbit/Class.cpp',
|
||||
'rabbit/ClassMember.cpp',
|
||||
'rabbit/Closure.cpp',
|
||||
'rabbit/Compiler.cpp',
|
||||
'rabbit/Delegable.cpp',
|
||||
'rabbit/ExceptionTrap.cpp',
|
||||
'rabbit/FuncState.cpp',
|
||||
'rabbit/FunctionInfo.cpp',
|
||||
'rabbit/FunctionProto.cpp',
|
||||
'rabbit/Generator.cpp',
|
||||
'rabbit/Hash.cpp',
|
||||
'rabbit/Instance.cpp',
|
||||
'rabbit/Instruction.cpp',
|
||||
'rabbit/Lexer.cpp',
|
||||
'rabbit/LineInfo.cpp',
|
||||
'rabbit/LocalVarInfo.cpp',
|
||||
'rabbit/MemberHandle.cpp',
|
||||
'rabbit/MetaMethod.cpp',
|
||||
'rabbit/NativeClosure.cpp',
|
||||
'rabbit/Object.cpp',
|
||||
'rabbit/ObjectPtr.cpp',
|
||||
'rabbit/ObjectType.cpp',
|
||||
'rabbit/ObjectValue.cpp',
|
||||
'rabbit/Outer.cpp',
|
||||
'rabbit/OuterVar.cpp',
|
||||
'rabbit/RefCounted.cpp',
|
||||
'rabbit/RefTable.cpp',
|
||||
'rabbit/RegFunction.cpp',
|
||||
'rabbit/SharedState.cpp',
|
||||
'rabbit/StackInfos.cpp',
|
||||
'rabbit/String.cpp',
|
||||
'rabbit/StringTable.cpp',
|
||||
'rabbit/Table.cpp',
|
||||
'rabbit/VirtualMachine.cpp',
|
||||
'rabbit/WeakRef.cpp',
|
||||
'rabbit/sqapi.cpp',
|
||||
'rabbit/sqbaselib.cpp',
|
||||
'rabbit/sqcompiler.cpp',
|
||||
'rabbit/sqdebug.cpp',
|
||||
'rabbit/sqfuncstate.cpp',
|
||||
'rabbit/sqlexer.cpp',
|
||||
'rabbit/sqmem.cpp',
|
||||
'rabbit/sqobject.cpp',
|
||||
])
|
||||
my_module.compile_version("c++", 2011)
|
||||
my_module.add_depend([
|
||||
'z',
|
||||
'm',
|
||||
'c',
|
||||
'etk-base',
|
||||
])
|
||||
'z',
|
||||
'm',
|
||||
'c',
|
||||
'etk-base',
|
||||
])
|
||||
my_module.add_header_file([
|
||||
'rabbit/Hash.hpp',
|
||||
'rabbit/RefTable.hpp',
|
||||
'rabbit/SharedState.hpp',
|
||||
'rabbit/String.hpp',
|
||||
'rabbit/StringTable.hpp',
|
||||
'rabbit/Table.hpp',
|
||||
'rabbit/Class.hpp',
|
||||
'rabbit/ClassMember.hpp',
|
||||
'rabbit/Instance.hpp',
|
||||
'rabbit/AutoDec.hpp',
|
||||
'rabbit/VirtualMachine.hpp',
|
||||
'rabbit/rabbit.hpp',
|
||||
'rabbit/sqobject.hpp',
|
||||
'rabbit/sqopcodes.hpp',
|
||||
'rabbit/UserData.hpp',
|
||||
'rabbit/squtils.hpp',
|
||||
'rabbit/sqpcheader.hpp',
|
||||
'rabbit/sqfuncproto.hpp',
|
||||
'rabbit/sqconfig.hpp',
|
||||
'rabbit/sqcompiler.hpp',
|
||||
'rabbit/Array.hpp',
|
||||
'rabbit/sqclosure.hpp',
|
||||
'rabbit/sqlexer.hpp',
|
||||
'rabbit/sqfuncstate.hpp',
|
||||
'rabbit/RefCounted.hpp',
|
||||
'rabbit/WeakRef.hpp',
|
||||
'rabbit/Delegable.hpp',
|
||||
'rabbit/ObjectType.hpp',
|
||||
'rabbit/ObjectValue.hpp',
|
||||
'rabbit/Object.hpp',
|
||||
'rabbit/ObjectPtr.hpp',
|
||||
'rabbit/MemberHandle.hpp',
|
||||
'rabbit/StackInfos.hpp',
|
||||
'rabbit/RegFunction.hpp',
|
||||
'rabbit/FunctionInfo.hpp',
|
||||
'rabbit/MetaMethod.hpp',
|
||||
'rabbit/ExceptionTrap.hpp',
|
||||
])
|
||||
'rabbit/Array.hpp',
|
||||
'rabbit/AutoDec.hpp',
|
||||
'rabbit/Class.hpp',
|
||||
'rabbit/ClassMember.hpp',
|
||||
'rabbit/Closure.hpp',
|
||||
'rabbit/Compiler.hpp',
|
||||
'rabbit/Delegable.hpp',
|
||||
'rabbit/ExceptionTrap.hpp',
|
||||
'rabbit/FuncState.hpp',
|
||||
'rabbit/FunctionInfo.hpp',
|
||||
'rabbit/FunctionProto.hpp',
|
||||
'rabbit/Generator.hpp',
|
||||
'rabbit/Hash.hpp',
|
||||
'rabbit/Instance.hpp',
|
||||
'rabbit/Instruction.hpp',
|
||||
'rabbit/Lexer.hpp',
|
||||
'rabbit/LineInfo.hpp',
|
||||
'rabbit/LocalVarInfo.hpp',
|
||||
'rabbit/MemberHandle.hpp',
|
||||
'rabbit/MetaMethod.hpp',
|
||||
'rabbit/NativeClosure.hpp',
|
||||
'rabbit/Object.hpp',
|
||||
'rabbit/ObjectPtr.hpp',
|
||||
'rabbit/ObjectType.hpp',
|
||||
'rabbit/ObjectValue.hpp',
|
||||
'rabbit/Outer.hpp',
|
||||
'rabbit/OuterVar.hpp',
|
||||
'rabbit/RefCounted.hpp',
|
||||
'rabbit/RefTable.hpp',
|
||||
'rabbit/RegFunction.hpp',
|
||||
'rabbit/SharedState.hpp',
|
||||
'rabbit/StackInfos.hpp',
|
||||
'rabbit/String.hpp',
|
||||
'rabbit/StringTable.hpp',
|
||||
'rabbit/Table.hpp',
|
||||
'rabbit/UserData.hpp',
|
||||
'rabbit/VirtualMachine.hpp',
|
||||
'rabbit/WeakRef.hpp',
|
||||
'rabbit/rabbit.hpp',
|
||||
'rabbit/sqclosure.hpp',
|
||||
'rabbit/sqcompiler.hpp',
|
||||
'rabbit/sqconfig.hpp',
|
||||
'rabbit/sqfuncproto.hpp',
|
||||
'rabbit/sqfuncstate.hpp',
|
||||
'rabbit/sqlexer.hpp',
|
||||
'rabbit/sqobject.hpp',
|
||||
'rabbit/sqopcodes.hpp',
|
||||
'rabbit/sqpcheader.hpp',
|
||||
'rabbit/squtils.hpp',
|
||||
])
|
||||
|
||||
return True
|
||||
|
||||
|
135
rabbit/Closure.cpp
Normal file
135
rabbit/Closure.cpp
Normal file
@ -0,0 +1,135 @@
|
||||
/**
|
||||
* @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/Closure.hpp>
|
||||
|
||||
|
||||
|
||||
#define _CHECK_IO(exp) { if(!exp)return false; }
|
||||
bool SafeWrite(rabbit::VirtualMachine* v,SQWRITEFUNC write,rabbit::UserPointer up,rabbit::UserPointer dest,int64_t size)
|
||||
{
|
||||
if(write(up,dest,size) != size) {
|
||||
v->raise_error(_SC("io error (write function failure)"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SafeRead(rabbit::VirtualMachine* v,SQWRITEFUNC read,rabbit::UserPointer up,rabbit::UserPointer dest,int64_t size)
|
||||
{
|
||||
if(size && read(up,dest,size) != size) {
|
||||
v->raise_error(_SC("io error, read function failure, the origin stream could be corrupted/trucated"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteTag(rabbit::VirtualMachine* v,SQWRITEFUNC write,rabbit::UserPointer up,uint32_t tag)
|
||||
{
|
||||
return SafeWrite(v,write,up,&tag,sizeof(tag));
|
||||
}
|
||||
|
||||
bool CheckTag(rabbit::VirtualMachine* v,SQWRITEFUNC read,rabbit::UserPointer up,uint32_t tag)
|
||||
{
|
||||
uint32_t t;
|
||||
_CHECK_IO(SafeRead(v,read,up,&t,sizeof(t)));
|
||||
if(t != tag){
|
||||
v->raise_error(_SC("invalid or corrupted closure stream"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteObject(rabbit::VirtualMachine* v,rabbit::UserPointer up,SQWRITEFUNC write,rabbit::ObjectPtr &o)
|
||||
{
|
||||
uint32_t _type = (uint32_t)sq_type(o);
|
||||
_CHECK_IO(SafeWrite(v,write,up,&_type,sizeof(_type)));
|
||||
switch(sq_type(o)){
|
||||
case rabbit::OT_STRING:
|
||||
_CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(int64_t)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,_stringval(o),sq_rsl(_string(o)->_len)));
|
||||
break;
|
||||
case rabbit::OT_BOOL:
|
||||
case rabbit::OT_INTEGER:
|
||||
_CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(int64_t)));break;
|
||||
case rabbit::OT_FLOAT:
|
||||
_CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(float_t)));break;
|
||||
case rabbit::OT_NULL:
|
||||
break;
|
||||
default:
|
||||
v->raise_error(_SC("cannot serialize a %s"),getTypeName(o));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReadObject(rabbit::VirtualMachine* v,rabbit::UserPointer up,SQREADFUNC read,rabbit::ObjectPtr &o)
|
||||
{
|
||||
uint32_t _type;
|
||||
_CHECK_IO(SafeRead(v,read,up,&_type,sizeof(_type)));
|
||||
rabbit::ObjectType t = (rabbit::ObjectType)_type;
|
||||
switch(t){
|
||||
case rabbit::OT_STRING:{
|
||||
int64_t len;
|
||||
_CHECK_IO(SafeRead(v,read,up,&len,sizeof(int64_t)));
|
||||
_CHECK_IO(SafeRead(v,read,up,_get_shared_state(v)->getScratchPad(sq_rsl(len)),sq_rsl(len)));
|
||||
o=rabbit::String::create(_get_shared_state(v),_get_shared_state(v)->getScratchPad(-1),len);
|
||||
}
|
||||
break;
|
||||
case rabbit::OT_INTEGER:{
|
||||
int64_t i;
|
||||
_CHECK_IO(SafeRead(v,read,up,&i,sizeof(int64_t))); o = i; break;
|
||||
}
|
||||
case rabbit::OT_BOOL:{
|
||||
int64_t i;
|
||||
_CHECK_IO(SafeRead(v,read,up,&i,sizeof(int64_t))); o._type = rabbit::OT_BOOL; o._unVal.nInteger = i; break;
|
||||
}
|
||||
case rabbit::OT_FLOAT:{
|
||||
float_t f;
|
||||
_CHECK_IO(SafeRead(v,read,up,&f,sizeof(float_t))); o = f; break;
|
||||
}
|
||||
case rabbit::OT_NULL:
|
||||
o.Null();
|
||||
break;
|
||||
default:
|
||||
v->raise_error(_SC("cannot serialize a %s"),IdType2Name(t));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rabbit::Closure::save(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQWRITEFUNC write)
|
||||
{
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD));
|
||||
_CHECK_IO(WriteTag(v,write,up,sizeof(rabbit::Char)));
|
||||
_CHECK_IO(WriteTag(v,write,up,sizeof(int64_t)));
|
||||
_CHECK_IO(WriteTag(v,write,up,sizeof(float_t)));
|
||||
_CHECK_IO(_function->save(v,up,write));
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rabbit::Closure::load(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQREADFUNC read,rabbit::ObjectPtr &ret)
|
||||
{
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD));
|
||||
_CHECK_IO(CheckTag(v,read,up,sizeof(rabbit::Char)));
|
||||
_CHECK_IO(CheckTag(v,read,up,sizeof(int64_t)));
|
||||
_CHECK_IO(CheckTag(v,read,up,sizeof(float_t)));
|
||||
rabbit::ObjectPtr func;
|
||||
_CHECK_IO(rabbit::FunctionProto::load(v,up,read,func));
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL));
|
||||
ret = rabbit::Closure::create(_get_shared_state(v),_funcproto(func),_table(v->_roottable)->getWeakRef(rabbit::OT_TABLE));
|
||||
//FIXME: load an root for this closure
|
||||
return true;
|
||||
}
|
||||
|
||||
rabbit::Closure::~Closure()
|
||||
{
|
||||
__Objrelease(_root);
|
||||
__Objrelease(_env);
|
||||
__Objrelease(_base);
|
||||
}
|
76
rabbit/Closure.hpp
Normal file
76
rabbit/Closure.hpp
Normal file
@ -0,0 +1,76 @@
|
||||
/**
|
||||
* @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
|
||||
|
||||
namespace rabbit {
|
||||
|
||||
#define _CALC_CLOSURE_SIZE(func) (sizeof(rabbit::Closure) + (func->_noutervalues*sizeof(rabbit::ObjectPtr)) + (func->_ndefaultparams*sizeof(rabbit::ObjectPtr)))
|
||||
|
||||
class Closure : public rabbit::RefCounted {
|
||||
private:
|
||||
Closure(rabbit::SharedState *ss,rabbit::FunctionProto *func){
|
||||
_function = func;
|
||||
__ObjaddRef(_function); _base = NULL;
|
||||
_env = NULL;
|
||||
_root=NULL;
|
||||
}
|
||||
public:
|
||||
static rabbit::Closure *create(rabbit::SharedState *ss,rabbit::FunctionProto *func,rabbit::WeakRef *root){
|
||||
int64_t size = _CALC_CLOSURE_SIZE(func);
|
||||
rabbit::Closure *nc=(rabbit::Closure*)SQ_MALLOC(size);
|
||||
new (nc) rabbit::Closure(ss,func);
|
||||
nc->_outervalues = (rabbit::ObjectPtr *)(nc + 1);
|
||||
nc->_defaultparams = &nc->_outervalues[func->_noutervalues];
|
||||
nc->_root = root;
|
||||
__ObjaddRef(nc->_root);
|
||||
_CONSTRUCT_VECTOR(rabbit::ObjectPtr,func->_noutervalues,nc->_outervalues);
|
||||
_CONSTRUCT_VECTOR(rabbit::ObjectPtr,func->_ndefaultparams,nc->_defaultparams);
|
||||
return nc;
|
||||
}
|
||||
void release(){
|
||||
rabbit::FunctionProto *f = _function;
|
||||
int64_t size = _CALC_CLOSURE_SIZE(f);
|
||||
_DESTRUCT_VECTOR(ObjectPtr,f->_noutervalues,_outervalues);
|
||||
_DESTRUCT_VECTOR(ObjectPtr,f->_ndefaultparams,_defaultparams);
|
||||
__Objrelease(_function);
|
||||
this->~rabbit::Closure();
|
||||
sq_vm_free(this,size);
|
||||
}
|
||||
void setRoot(rabbit::WeakRef *r)
|
||||
{
|
||||
__Objrelease(_root);
|
||||
_root = r;
|
||||
__ObjaddRef(_root);
|
||||
}
|
||||
rabbit::Closure *clone()
|
||||
{
|
||||
rabbit::FunctionProto *f = _function;
|
||||
rabbit::Closure * ret = rabbit::Closure::create(NULL,f,_root);
|
||||
ret->_env = _env;
|
||||
if(ret->_env) __ObjaddRef(ret->_env);
|
||||
_COPY_VECTOR(ret->_outervalues,_outervalues,f->_noutervalues);
|
||||
_COPY_VECTOR(ret->_defaultparams,_defaultparams,f->_ndefaultparams);
|
||||
return ret;
|
||||
}
|
||||
~rabbit::Closure();
|
||||
|
||||
bool save(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQWRITEFUNC write);
|
||||
static bool load(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQREADFUNC read,rabbit::ObjectPtr &ret);
|
||||
rabbit::WeakRef *_env;
|
||||
rabbit::WeakRef *_root;
|
||||
rabbit::Class *_base;
|
||||
rabbit::FunctionProto *_function;
|
||||
rabbit::ObjectPtr *_outervalues;
|
||||
rabbit::ObjectPtr *_defaultparams;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R'))
|
||||
#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T'))
|
||||
#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L'))
|
@ -5,6 +5,8 @@
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#include <rabbit/Compiler.hpp>
|
||||
|
||||
#include <rabbit/sqpcheader.hpp>
|
||||
#ifndef NO_COMPILER
|
||||
#include <stdarg.h>
|
||||
@ -73,10 +75,10 @@ struct SQScope {
|
||||
if(__nbreaks__>0)ResolveBreaks(_fs,__nbreaks__); \
|
||||
_fs->_breaktargets.popBack();_fs->_continuetargets.popBack();}
|
||||
|
||||
class SQcompiler
|
||||
class rabbit::Compiler
|
||||
{
|
||||
public:
|
||||
SQcompiler(rabbit::VirtualMachine *v, SQLEXREADFUNC rg, rabbit::UserPointer up, const rabbit::Char* sourcename, bool raiseerror, bool lineinfo)
|
||||
rabbit::Compiler(rabbit::VirtualMachine *v, SQLEXREADFUNC rg, rabbit::UserPointer up, const rabbit::Char* sourcename, bool raiseerror, bool lineinfo)
|
||||
{
|
||||
_vm=v;
|
||||
_lex.init(_get_shared_state(v), rg, up,Throwerror,this);
|
||||
@ -87,7 +89,7 @@ public:
|
||||
_compilererror[0] = _SC('\0');
|
||||
}
|
||||
static void Throwerror(void *ud, const rabbit::Char *s) {
|
||||
SQcompiler *c = (SQcompiler *)ud;
|
||||
rabbit::Compiler *c = (rabbit::Compiler *)ud;
|
||||
c->error(s);
|
||||
}
|
||||
void error(const rabbit::Char *s, ...)
|
||||
@ -170,7 +172,7 @@ public:
|
||||
_debugline = 1;
|
||||
_debugop = 0;
|
||||
|
||||
SQFuncState funcstate(_get_shared_state(_vm), NULL,Throwerror,this);
|
||||
FuncState funcstate(_get_shared_state(_vm), NULL,Throwerror,this);
|
||||
funcstate._name = rabbit::String::create(_get_shared_state(_vm), _SC("main"));
|
||||
_fs = &funcstate;
|
||||
_fs->addParameter(_fs->createString(_SC("this")));
|
||||
@ -481,7 +483,7 @@ public:
|
||||
_fs->addInstruction(_OP_OR, trg, 0, first_exp, 0);
|
||||
int64_t jpos = _fs->getCurrentPos();
|
||||
if(trg != first_exp) _fs->addInstruction(_OP_MOVE, trg, first_exp);
|
||||
Lex(); INVOKE_EXP(&SQcompiler::LogicalOrExp);
|
||||
Lex(); INVOKE_EXP(&rabbit::Compiler::LogicalOrExp);
|
||||
_fs->snoozeOpt();
|
||||
int64_t second_exp = _fs->popTarget();
|
||||
if(trg != second_exp) _fs->addInstruction(_OP_MOVE, trg, second_exp);
|
||||
@ -501,7 +503,7 @@ public:
|
||||
_fs->addInstruction(_OP_AND, trg, 0, first_exp, 0);
|
||||
int64_t jpos = _fs->getCurrentPos();
|
||||
if(trg != first_exp) _fs->addInstruction(_OP_MOVE, trg, first_exp);
|
||||
Lex(); INVOKE_EXP(&SQcompiler::LogicalAndExp);
|
||||
Lex(); INVOKE_EXP(&rabbit::Compiler::LogicalAndExp);
|
||||
_fs->snoozeOpt();
|
||||
int64_t second_exp = _fs->popTarget();
|
||||
if(trg != second_exp) _fs->addInstruction(_OP_MOVE, trg, second_exp);
|
||||
@ -519,30 +521,30 @@ public:
|
||||
{
|
||||
BitwiseXorExp();
|
||||
for(;;) if(_token == _SC('|'))
|
||||
{BIN_EXP(_OP_BITW, &SQcompiler::BitwiseXorExp,BW_OR);
|
||||
{BIN_EXP(_OP_BITW, &rabbit::Compiler::BitwiseXorExp,BW_OR);
|
||||
}else return;
|
||||
}
|
||||
void BitwiseXorExp()
|
||||
{
|
||||
BitwiseAndExp();
|
||||
for(;;) if(_token == _SC('^'))
|
||||
{BIN_EXP(_OP_BITW, &SQcompiler::BitwiseAndExp,BW_XOR);
|
||||
{BIN_EXP(_OP_BITW, &rabbit::Compiler::BitwiseAndExp,BW_XOR);
|
||||
}else return;
|
||||
}
|
||||
void BitwiseAndExp()
|
||||
{
|
||||
EqExp();
|
||||
for(;;) if(_token == _SC('&'))
|
||||
{BIN_EXP(_OP_BITW, &SQcompiler::EqExp,BW_AND);
|
||||
{BIN_EXP(_OP_BITW, &rabbit::Compiler::EqExp,BW_AND);
|
||||
}else return;
|
||||
}
|
||||
void EqExp()
|
||||
{
|
||||
CompExp();
|
||||
for(;;) switch(_token) {
|
||||
case TK_EQ: BIN_EXP(_OP_EQ, &SQcompiler::CompExp); break;
|
||||
case TK_NE: BIN_EXP(_OP_NE, &SQcompiler::CompExp); break;
|
||||
case TK_3WAYSCMP: BIN_EXP(_OP_CMP, &SQcompiler::CompExp,CMP_3W); break;
|
||||
case TK_EQ: BIN_EXP(_OP_EQ, &rabbit::Compiler::CompExp); break;
|
||||
case TK_NE: BIN_EXP(_OP_NE, &rabbit::Compiler::CompExp); break;
|
||||
case TK_3WAYSCMP: BIN_EXP(_OP_CMP, &rabbit::Compiler::CompExp,CMP_3W); break;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
@ -550,12 +552,12 @@ public:
|
||||
{
|
||||
ShiftExp();
|
||||
for(;;) switch(_token) {
|
||||
case _SC('>'): BIN_EXP(_OP_CMP, &SQcompiler::ShiftExp,CMP_G); break;
|
||||
case _SC('<'): BIN_EXP(_OP_CMP, &SQcompiler::ShiftExp,CMP_L); break;
|
||||
case TK_GE: BIN_EXP(_OP_CMP, &SQcompiler::ShiftExp,CMP_GE); break;
|
||||
case TK_LE: BIN_EXP(_OP_CMP, &SQcompiler::ShiftExp,CMP_LE); break;
|
||||
case TK_IN: BIN_EXP(_OP_EXISTS, &SQcompiler::ShiftExp); break;
|
||||
case TK_INSTANCEOF: BIN_EXP(_OP_INSTANCEOF, &SQcompiler::ShiftExp); break;
|
||||
case _SC('>'): BIN_EXP(_OP_CMP, &rabbit::Compiler::ShiftExp,CMP_G); break;
|
||||
case _SC('<'): BIN_EXP(_OP_CMP, &rabbit::Compiler::ShiftExp,CMP_L); break;
|
||||
case TK_GE: BIN_EXP(_OP_CMP, &rabbit::Compiler::ShiftExp,CMP_GE); break;
|
||||
case TK_LE: BIN_EXP(_OP_CMP, &rabbit::Compiler::ShiftExp,CMP_LE); break;
|
||||
case TK_IN: BIN_EXP(_OP_EXISTS, &rabbit::Compiler::ShiftExp); break;
|
||||
case TK_INSTANCEOF: BIN_EXP(_OP_INSTANCEOF, &rabbit::Compiler::ShiftExp); break;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
@ -563,9 +565,9 @@ public:
|
||||
{
|
||||
PlusExp();
|
||||
for(;;) switch(_token) {
|
||||
case TK_USHIFTR: BIN_EXP(_OP_BITW, &SQcompiler::PlusExp,BW_USHIFTR); break;
|
||||
case TK_SHIFTL: BIN_EXP(_OP_BITW, &SQcompiler::PlusExp,BW_SHIFTL); break;
|
||||
case TK_SHIFTR: BIN_EXP(_OP_BITW, &SQcompiler::PlusExp,BW_SHIFTR); break;
|
||||
case TK_USHIFTR: BIN_EXP(_OP_BITW, &rabbit::Compiler::PlusExp,BW_USHIFTR); break;
|
||||
case TK_SHIFTL: BIN_EXP(_OP_BITW, &rabbit::Compiler::PlusExp,BW_SHIFTL); break;
|
||||
case TK_SHIFTR: BIN_EXP(_OP_BITW, &rabbit::Compiler::PlusExp,BW_SHIFTR); break;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
@ -600,7 +602,7 @@ public:
|
||||
MultExp();
|
||||
for(;;) switch(_token) {
|
||||
case _SC('+'): case _SC('-'):
|
||||
BIN_EXP(ChooseArithOpByToken(_token), &SQcompiler::MultExp); break;
|
||||
BIN_EXP(ChooseArithOpByToken(_token), &rabbit::Compiler::MultExp); break;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
@ -610,7 +612,7 @@ public:
|
||||
PrefixedExpr();
|
||||
for(;;) switch(_token) {
|
||||
case _SC('*'): case _SC('/'): case _SC('%'):
|
||||
BIN_EXP(ChooseArithOpByToken(_token), &SQcompiler::PrefixedExpr); break;
|
||||
BIN_EXP(ChooseArithOpByToken(_token), &rabbit::Compiler::PrefixedExpr); break;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
@ -1160,7 +1162,7 @@ public:
|
||||
_fs->snoozeOpt();
|
||||
int64_t expend = _fs->getCurrentPos();
|
||||
int64_t expsize = (expend - expstart) + 1;
|
||||
SQInstructionVec exp;
|
||||
rabbit::InstructionVec exp;
|
||||
if(expsize > 0) {
|
||||
for(int64_t i = 0; i < expsize; i++)
|
||||
exp.pushBack(_fs->getInstruction(expstart + i));
|
||||
@ -1490,7 +1492,7 @@ public:
|
||||
}
|
||||
void createFunction(rabbit::Object &name,bool lambda = false)
|
||||
{
|
||||
SQFuncState *funcstate = _fs->pushChildState(_get_shared_state(_vm));
|
||||
FuncState *funcstate = _fs->pushChildState(_get_shared_state(_vm));
|
||||
funcstate->_name = name;
|
||||
rabbit::Object paramname;
|
||||
funcstate->addParameter(_fs->createString(_SC("this")));
|
||||
@ -1526,7 +1528,7 @@ public:
|
||||
_fs->popTarget();
|
||||
}
|
||||
|
||||
SQFuncState *currchunk = _fs;
|
||||
FuncState *currchunk = _fs;
|
||||
_fs = funcstate;
|
||||
if(lambda) {
|
||||
Expression();
|
||||
@ -1538,7 +1540,7 @@ public:
|
||||
funcstate->addInstruction(_OP_RETURN, -1);
|
||||
funcstate->setStacksize(0);
|
||||
|
||||
SQFunctionProto *func = funcstate->buildProto();
|
||||
rabbit::FunctionProto *func = funcstate->buildProto();
|
||||
#ifdef _DEBUG_DUMP
|
||||
funcstate->dump(func);
|
||||
#endif
|
||||
@ -1546,7 +1548,7 @@ public:
|
||||
_fs->_functions.pushBack(func);
|
||||
_fs->popChildState();
|
||||
}
|
||||
void ResolveBreaks(SQFuncState *funcstate, int64_t ntoresolve)
|
||||
void ResolveBreaks(FuncState *funcstate, int64_t ntoresolve)
|
||||
{
|
||||
while(ntoresolve > 0) {
|
||||
int64_t pos = funcstate->_unresolvedbreaks.back();
|
||||
@ -1556,7 +1558,7 @@ public:
|
||||
ntoresolve--;
|
||||
}
|
||||
}
|
||||
void ResolveContinues(SQFuncState *funcstate, int64_t ntoresolve, int64_t targetpos)
|
||||
void ResolveContinues(FuncState *funcstate, int64_t ntoresolve, int64_t targetpos)
|
||||
{
|
||||
while(ntoresolve > 0) {
|
||||
int64_t pos = funcstate->_unresolvedcontinues.back();
|
||||
@ -1568,9 +1570,9 @@ public:
|
||||
}
|
||||
private:
|
||||
int64_t _token;
|
||||
SQFuncState *_fs;
|
||||
FuncState *_fs;
|
||||
rabbit::ObjectPtr _sourcename;
|
||||
SQLexer _lex;
|
||||
rabbit::Lexer _lex;
|
||||
bool _lineinfo;
|
||||
bool _raiseerror;
|
||||
int64_t _debugline;
|
||||
@ -1584,7 +1586,7 @@ private:
|
||||
|
||||
bool compile(rabbit::VirtualMachine *vm,SQLEXREADFUNC rg, rabbit::UserPointer up, const rabbit::Char *sourcename, rabbit::ObjectPtr &out, bool raiseerror, bool lineinfo)
|
||||
{
|
||||
SQcompiler p(vm, rg, up, sourcename, raiseerror, lineinfo);
|
||||
rabbit::Compiler p(vm, rg, up, sourcename, raiseerror, lineinfo);
|
||||
return p.compile(out);
|
||||
}
|
||||
|
84
rabbit/Compiler.hpp
Normal file
84
rabbit/Compiler.hpp
Normal file
@ -0,0 +1,84 @@
|
||||
/**
|
||||
* @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
|
||||
|
||||
namespace rabbit {
|
||||
#define TK_IDENTIFIER 258
|
||||
#define TK_STRING_LITERAL 259
|
||||
#define TK_INTEGER 260
|
||||
#define TK_FLOAT 261
|
||||
#define TK_BASE 262
|
||||
#define TK_DELETE 263
|
||||
#define TK_EQ 264
|
||||
#define TK_NE 265
|
||||
#define TK_LE 266
|
||||
#define TK_GE 267
|
||||
#define TK_SWITCH 268
|
||||
#define TK_ARROW 269
|
||||
#define TK_AND 270
|
||||
#define TK_OR 271
|
||||
#define TK_IF 272
|
||||
#define TK_ELSE 273
|
||||
#define TK_WHILE 274
|
||||
#define TK_BREAK 275
|
||||
#define TK_FOR 276
|
||||
#define TK_DO 277
|
||||
#define TK_NULL 278
|
||||
#define TK_FOREACH 279
|
||||
#define TK_IN 280
|
||||
#define TK_NEWSLOT 281
|
||||
#define TK_MODULO 282
|
||||
#define TK_LOCAL 283
|
||||
#define TK_CLONE 284
|
||||
#define TK_FUNCTION 285
|
||||
#define TK_RETURN 286
|
||||
#define TK_TYPEOF 287
|
||||
#define TK_UMINUS 288
|
||||
#define TK_PLUSEQ 289
|
||||
#define TK_MINUSEQ 290
|
||||
#define TK_CONTINUE 291
|
||||
#define TK_YIELD 292
|
||||
#define TK_TRY 293
|
||||
#define TK_CATCH 294
|
||||
#define TK_THROW 295
|
||||
#define TK_SHIFTL 296
|
||||
#define TK_SHIFTR 297
|
||||
#define TK_RESUME 298
|
||||
#define TK_DOUBLE_COLON 299
|
||||
#define TK_CASE 300
|
||||
#define TK_DEFAULT 301
|
||||
#define TK_THIS 302
|
||||
#define TK_PLUSPLUS 303
|
||||
#define TK_MINUSMINUS 304
|
||||
#define TK_3WAYSCMP 305
|
||||
#define TK_USHIFTR 306
|
||||
#define TK_CLASS 307
|
||||
#define TK_EXTENDS 308
|
||||
#define TK_CONSTRUCTOR 310
|
||||
#define TK_INSTANCEOF 311
|
||||
#define TK_VARPARAMS 312
|
||||
#define TK___LINE__ 313
|
||||
#define TK___FILE__ 314
|
||||
#define TK_TRUE 315
|
||||
#define TK_FALSE 316
|
||||
#define TK_MULEQ 317
|
||||
#define TK_DIVEQ 318
|
||||
#define TK_MODEQ 319
|
||||
#define TK_ATTR_OPEN 320
|
||||
#define TK_ATTR_CLOSE 321
|
||||
#define TK_STATIC 322
|
||||
#define TK_ENUM 323
|
||||
#define TK_CONST 324
|
||||
#define TK_RAWCALL 325
|
||||
|
||||
|
||||
|
||||
typedef void(*compilererrorFunc)(void *ud, const rabbit::Char *s);
|
||||
bool compile(rabbit::VirtualMachine *vm, SQLEXREADFUNC rg, rabbit::UserPointer up, const rabbit::Char *sourcename, rabbit::ObjectPtr &out, bool raiseerror, bool lineinfo);
|
||||
|
||||
}
|
@ -10,7 +10,7 @@
|
||||
#include <etk/types.hpp>
|
||||
#include <rabbit/sqconfig.hpp>
|
||||
|
||||
struct SQInstruction;
|
||||
struct rabbit::Instruction;
|
||||
namespace rabbit {
|
||||
class ExceptionTrap {
|
||||
public:
|
||||
@ -19,7 +19,7 @@ namespace rabbit {
|
||||
}
|
||||
ExceptionTrap(int64_t ss,
|
||||
int64_t stackbase,
|
||||
SQInstruction *ip,
|
||||
rabbit::Instruction *ip,
|
||||
int64_t ex_target) {
|
||||
_stacksize = ss;
|
||||
_stackbase = stackbase;
|
||||
@ -32,7 +32,7 @@ namespace rabbit {
|
||||
|
||||
int64_t _stackbase;
|
||||
int64_t _stacksize;
|
||||
SQInstruction *_ip;
|
||||
rabbit::Instruction *_ip;
|
||||
int64_t _extarget;
|
||||
};
|
||||
}
|
||||
|
@ -5,18 +5,18 @@
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#include <rabbit/FuncState.hpp>
|
||||
|
||||
#include <rabbit/sqpcheader.hpp>
|
||||
#ifndef NO_COMPILER
|
||||
#include <rabbit/sqcompiler.hpp>
|
||||
#include <rabbit/Compiler.hpp>
|
||||
|
||||
#include <rabbit/sqfuncproto.hpp>
|
||||
#include <rabbit/FuncProto.hpp>
|
||||
|
||||
#include <rabbit/sqopcodes.hpp>
|
||||
#include <rabbit/sqfuncstate.hpp>
|
||||
|
||||
#ifdef _DEBUG_DUMP
|
||||
SQInstructionDesc g_InstrDesc[]={
|
||||
rabbit::InstructionDesc g_InstrDesc[]={
|
||||
{_SC("_OP_LINE")},
|
||||
{_SC("_OP_LOAD")},
|
||||
{_SC("_OP_LOADINT")},
|
||||
@ -91,7 +91,7 @@ void dumpLiteral(rabbit::ObjectPtr &o)
|
||||
}
|
||||
}
|
||||
|
||||
SQFuncState::SQFuncState(rabbit::SharedState *ss,SQFuncState *parent,compilererrorFunc efunc,void *ed)
|
||||
FuncState::rabbit::FuncState(rabbit::SharedState *ss,rabbit::FuncState *parent,compilererrorFunc efunc,void *ed)
|
||||
{
|
||||
_nliterals = 0;
|
||||
_literals = rabbit::Table::create(ss,0);
|
||||
@ -112,17 +112,17 @@ SQFuncState::SQFuncState(rabbit::SharedState *ss,SQFuncState *parent,compilererr
|
||||
|
||||
}
|
||||
|
||||
void SQFuncState::error(const rabbit::Char *err)
|
||||
void FuncState::error(const rabbit::Char *err)
|
||||
{
|
||||
_errfunc(_errtarget,err);
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_DUMP
|
||||
void SQFuncState::dump(SQFunctionProto *func)
|
||||
void FuncState::dump(rabbit::FunctionProto *func)
|
||||
{
|
||||
uint64_t n=0,i;
|
||||
int64_t si;
|
||||
scprintf(_SC("SQInstruction sizeof %d\n"),(int32_t)sizeof(SQInstruction));
|
||||
scprintf(_SC("rabbit::Instruction sizeof %d\n"),(int32_t)sizeof(rabbit::Instruction));
|
||||
scprintf(_SC("rabbit::Object sizeof %d\n"), (int32_t)sizeof(rabbit::Object));
|
||||
scprintf(_SC("--------------------------------------------------------------------\n"));
|
||||
scprintf(_SC("*****FUNCTION [%s]\n"),sq_type(func->_name)==rabbit::OT_STRING?_stringval(func->_name):_SC("unknown"));
|
||||
@ -153,20 +153,20 @@ void SQFuncState::dump(SQFunctionProto *func)
|
||||
}
|
||||
scprintf(_SC("-----LOCALS\n"));
|
||||
for(si=0;si<func->_nlocalvarinfos;si++){
|
||||
SQLocalVarInfo lvi=func->_localvarinfos[si];
|
||||
rabbit::LocalVarInfo lvi=func->_localvarinfos[si];
|
||||
scprintf(_SC("[%d] %s \t%d %d\n"), (int32_t)lvi._pos,_stringval(lvi._name), (int32_t)lvi._start_op, (int32_t)lvi._end_op);
|
||||
n++;
|
||||
}
|
||||
scprintf(_SC("-----LINE INFO\n"));
|
||||
for(i=0;i<_lineinfos.size();i++){
|
||||
SQLineInfo li=_lineinfos[i];
|
||||
rabbit::LineInfo li=_lineinfos[i];
|
||||
scprintf(_SC("op [%d] line [%d] \n"), (int32_t)li._op, (int32_t)li._line);
|
||||
n++;
|
||||
}
|
||||
scprintf(_SC("-----dump\n"));
|
||||
n=0;
|
||||
for(i=0;i<_instructions.size();i++){
|
||||
SQInstruction &inst=_instructions[i];
|
||||
rabbit::Instruction &inst=_instructions[i];
|
||||
if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){
|
||||
|
||||
int64_t lidx = inst._arg1;
|
||||
@ -217,17 +217,17 @@ void SQFuncState::dump(SQFunctionProto *func)
|
||||
}
|
||||
#endif
|
||||
|
||||
int64_t SQFuncState::getNumericConstant(const int64_t cons)
|
||||
int64_t FuncState::getNumericConstant(const int64_t cons)
|
||||
{
|
||||
return getConstant(rabbit::ObjectPtr(cons));
|
||||
}
|
||||
|
||||
int64_t SQFuncState::getNumericConstant(const float_t cons)
|
||||
int64_t FuncState::getNumericConstant(const float_t cons)
|
||||
{
|
||||
return getConstant(rabbit::ObjectPtr(cons));
|
||||
}
|
||||
|
||||
int64_t SQFuncState::getConstant(const rabbit::Object &cons)
|
||||
int64_t FuncState::getConstant(const rabbit::Object &cons)
|
||||
{
|
||||
rabbit::ObjectPtr val;
|
||||
if(!_table(_literals)->get(cons,val))
|
||||
@ -243,7 +243,7 @@ int64_t SQFuncState::getConstant(const rabbit::Object &cons)
|
||||
return _integer(val);
|
||||
}
|
||||
|
||||
void SQFuncState::setIntructionParams(int64_t pos,int64_t arg0,int64_t arg1,int64_t arg2,int64_t arg3)
|
||||
void FuncState::setIntructionParams(int64_t pos,int64_t arg0,int64_t arg1,int64_t arg2,int64_t arg3)
|
||||
{
|
||||
_instructions[pos]._arg0=(unsigned char)*((uint64_t *)&arg0);
|
||||
_instructions[pos]._arg1=(int32_t)*((uint64_t *)&arg1);
|
||||
@ -251,7 +251,7 @@ void SQFuncState::setIntructionParams(int64_t pos,int64_t arg0,int64_t arg1,int6
|
||||
_instructions[pos]._arg3=(unsigned char)*((uint64_t *)&arg3);
|
||||
}
|
||||
|
||||
void SQFuncState::setIntructionParam(int64_t pos,int64_t arg,int64_t val)
|
||||
void FuncState::setIntructionParam(int64_t pos,int64_t arg,int64_t val)
|
||||
{
|
||||
switch(arg){
|
||||
case 0:_instructions[pos]._arg0=(unsigned char)*((uint64_t *)&val);break;
|
||||
@ -261,10 +261,10 @@ void SQFuncState::setIntructionParam(int64_t pos,int64_t arg,int64_t val)
|
||||
};
|
||||
}
|
||||
|
||||
int64_t SQFuncState::allocStackPos()
|
||||
int64_t FuncState::allocStackPos()
|
||||
{
|
||||
int64_t npos=_vlocals.size();
|
||||
_vlocals.pushBack(SQLocalVarInfo());
|
||||
_vlocals.pushBack(rabbit::LocalVarInfo());
|
||||
if(_vlocals.size()>((uint64_t)_stacksize)) {
|
||||
if(_stacksize>MAX_FUNC_STACKSIZE) error(_SC("internal compiler error: too many locals"));
|
||||
_stacksize=_vlocals.size();
|
||||
@ -272,7 +272,7 @@ int64_t SQFuncState::allocStackPos()
|
||||
return npos;
|
||||
}
|
||||
|
||||
int64_t SQFuncState::pushTarget(int64_t n)
|
||||
int64_t FuncState::pushTarget(int64_t n)
|
||||
{
|
||||
if(n!=-1){
|
||||
_targetstack.pushBack(n);
|
||||
@ -283,18 +283,18 @@ int64_t SQFuncState::pushTarget(int64_t n)
|
||||
return n;
|
||||
}
|
||||
|
||||
int64_t SQFuncState::getUpTarget(int64_t n){
|
||||
int64_t FuncState::getUpTarget(int64_t n){
|
||||
return _targetstack[((_targetstack.size()-1)-n)];
|
||||
}
|
||||
|
||||
int64_t SQFuncState::topTarget(){
|
||||
int64_t FuncState::topTarget(){
|
||||
return _targetstack.back();
|
||||
}
|
||||
int64_t SQFuncState::popTarget()
|
||||
int64_t FuncState::popTarget()
|
||||
{
|
||||
uint64_t npos=_targetstack.back();
|
||||
assert(npos < _vlocals.size());
|
||||
SQLocalVarInfo &t = _vlocals[npos];
|
||||
rabbit::LocalVarInfo &t = _vlocals[npos];
|
||||
if(sq_type(t._name)==rabbit::OT_NULL){
|
||||
_vlocals.popBack();
|
||||
}
|
||||
@ -302,17 +302,17 @@ int64_t SQFuncState::popTarget()
|
||||
return npos;
|
||||
}
|
||||
|
||||
int64_t SQFuncState::getStacksize()
|
||||
int64_t FuncState::getStacksize()
|
||||
{
|
||||
return _vlocals.size();
|
||||
}
|
||||
|
||||
int64_t SQFuncState::CountOuters(int64_t stacksize)
|
||||
int64_t FuncState::CountOuters(int64_t stacksize)
|
||||
{
|
||||
int64_t outers = 0;
|
||||
int64_t k = _vlocals.size() - 1;
|
||||
while(k >= stacksize) {
|
||||
SQLocalVarInfo &lvi = _vlocals[k];
|
||||
rabbit::LocalVarInfo &lvi = _vlocals[k];
|
||||
k--;
|
||||
if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer
|
||||
outers++;
|
||||
@ -321,12 +321,12 @@ int64_t SQFuncState::CountOuters(int64_t stacksize)
|
||||
return outers;
|
||||
}
|
||||
|
||||
void SQFuncState::setStacksize(int64_t n)
|
||||
void FuncState::setStacksize(int64_t n)
|
||||
{
|
||||
int64_t size=_vlocals.size();
|
||||
while(size>n){
|
||||
size--;
|
||||
SQLocalVarInfo lvi = _vlocals.back();
|
||||
rabbit::LocalVarInfo lvi = _vlocals.back();
|
||||
if(sq_type(lvi._name)!=rabbit::OT_NULL){
|
||||
if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer
|
||||
_outers--;
|
||||
@ -338,7 +338,7 @@ void SQFuncState::setStacksize(int64_t n)
|
||||
}
|
||||
}
|
||||
|
||||
bool SQFuncState::isConstant(const rabbit::Object &name,rabbit::Object &e)
|
||||
bool FuncState::isConstant(const rabbit::Object &name,rabbit::Object &e)
|
||||
{
|
||||
rabbit::ObjectPtr val;
|
||||
if(_table(_sharedstate->_consts)->get(name,val)) {
|
||||
@ -348,17 +348,17 @@ bool SQFuncState::isConstant(const rabbit::Object &name,rabbit::Object &e)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SQFuncState::isLocal(uint64_t stkpos)
|
||||
bool FuncState::isLocal(uint64_t stkpos)
|
||||
{
|
||||
if(stkpos>=_vlocals.size())return false;
|
||||
else if(sq_type(_vlocals[stkpos]._name)!=rabbit::OT_NULL)return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t SQFuncState::pushLocalVariable(const rabbit::Object &name)
|
||||
int64_t FuncState::pushLocalVariable(const rabbit::Object &name)
|
||||
{
|
||||
int64_t pos=_vlocals.size();
|
||||
SQLocalVarInfo lvi;
|
||||
rabbit::LocalVarInfo lvi;
|
||||
lvi._name=name;
|
||||
lvi._start_op=getCurrentPos()+1;
|
||||
lvi._pos=_vlocals.size();
|
||||
@ -369,11 +369,11 @@ int64_t SQFuncState::pushLocalVariable(const rabbit::Object &name)
|
||||
|
||||
|
||||
|
||||
int64_t SQFuncState::getLocalVariable(const rabbit::Object &name)
|
||||
int64_t FuncState::getLocalVariable(const rabbit::Object &name)
|
||||
{
|
||||
int64_t locals=_vlocals.size();
|
||||
while(locals>=1){
|
||||
SQLocalVarInfo &lvi = _vlocals[locals-1];
|
||||
rabbit::LocalVarInfo &lvi = _vlocals[locals-1];
|
||||
if(sq_type(lvi._name)==rabbit::OT_STRING && _string(lvi._name)==_string(name)){
|
||||
return locals-1;
|
||||
}
|
||||
@ -382,14 +382,14 @@ int64_t SQFuncState::getLocalVariable(const rabbit::Object &name)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void SQFuncState::markLocalAsOuter(int64_t pos)
|
||||
void FuncState::markLocalAsOuter(int64_t pos)
|
||||
{
|
||||
SQLocalVarInfo &lvi = _vlocals[pos];
|
||||
rabbit::LocalVarInfo &lvi = _vlocals[pos];
|
||||
lvi._end_op = UINT_MINUS_ONE;
|
||||
_outers++;
|
||||
}
|
||||
|
||||
int64_t SQFuncState::getOuterVariable(const rabbit::Object &name)
|
||||
int64_t FuncState::getOuterVariable(const rabbit::Object &name)
|
||||
{
|
||||
int64_t outers = _outervalues.size();
|
||||
for(int64_t i = 0; i<outers; i++) {
|
||||
@ -402,13 +402,13 @@ int64_t SQFuncState::getOuterVariable(const rabbit::Object &name)
|
||||
if(pos == -1) {
|
||||
pos = _parent->getOuterVariable(name);
|
||||
if(pos != -1) {
|
||||
_outervalues.pushBack(SQOuterVar(name,rabbit::ObjectPtr(int64_t(pos)),otOUTER)); //local
|
||||
_outervalues.pushBack(rabbit::OuterVar(name,rabbit::ObjectPtr(int64_t(pos)),otOUTER)); //local
|
||||
return _outervalues.size() - 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
_parent->markLocalAsOuter(pos);
|
||||
_outervalues.pushBack(SQOuterVar(name,rabbit::ObjectPtr(int64_t(pos)),otLOCAL)); //local
|
||||
_outervalues.pushBack(rabbit::OuterVar(name,rabbit::ObjectPtr(int64_t(pos)),otLOCAL)); //local
|
||||
return _outervalues.size() - 1;
|
||||
|
||||
|
||||
@ -417,16 +417,16 @@ int64_t SQFuncState::getOuterVariable(const rabbit::Object &name)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void SQFuncState::addParameter(const rabbit::Object &name)
|
||||
void FuncState::addParameter(const rabbit::Object &name)
|
||||
{
|
||||
pushLocalVariable(name);
|
||||
_parameters.pushBack(name);
|
||||
}
|
||||
|
||||
void SQFuncState::addLineInfos(int64_t line,bool lineop,bool force)
|
||||
void FuncState::addLineInfos(int64_t line,bool lineop,bool force)
|
||||
{
|
||||
if(_lastline!=line || force){
|
||||
SQLineInfo li;
|
||||
rabbit::LineInfo li;
|
||||
li._line=line;li._op=(getCurrentPos()+1);
|
||||
if(lineop)addInstruction(_OP_LINE,0,line);
|
||||
if(_lastline!=line) {
|
||||
@ -436,12 +436,12 @@ void SQFuncState::addLineInfos(int64_t line,bool lineop,bool force)
|
||||
}
|
||||
}
|
||||
|
||||
void SQFuncState::discardTarget()
|
||||
void FuncState::discardTarget()
|
||||
{
|
||||
int64_t discardedtarget = popTarget();
|
||||
int64_t size = _instructions.size();
|
||||
if(size > 0 && _optimization){
|
||||
SQInstruction &pi = _instructions[size-1];//previous instruction
|
||||
rabbit::Instruction &pi = _instructions[size-1];//previous instruction
|
||||
switch(pi.op) {
|
||||
case _OP_SET:case _OP_NEWSLOT:case _OP_SETOUTER:case _OP_CALL:
|
||||
if(pi._arg0 == discardedtarget) {
|
||||
@ -451,11 +451,11 @@ void SQFuncState::discardTarget()
|
||||
}
|
||||
}
|
||||
|
||||
void SQFuncState::addInstruction(SQInstruction &i)
|
||||
void FuncState::addInstruction(rabbit::Instruction &i)
|
||||
{
|
||||
int64_t size = _instructions.size();
|
||||
if(size > 0 && _optimization){ //simple optimizer
|
||||
SQInstruction &pi = _instructions[size-1];//previous instruction
|
||||
rabbit::Instruction &pi = _instructions[size-1];//previous instruction
|
||||
switch(i.op) {
|
||||
case _OP_JZ:
|
||||
if( pi.op == _OP_CMP && pi._arg1 < 0xFF) {
|
||||
@ -584,24 +584,24 @@ void SQFuncState::addInstruction(SQInstruction &i)
|
||||
_instructions.pushBack(i);
|
||||
}
|
||||
|
||||
rabbit::Object SQFuncState::createString(const rabbit::Char *s,int64_t len)
|
||||
rabbit::Object FuncState::createString(const rabbit::Char *s,int64_t len)
|
||||
{
|
||||
rabbit::ObjectPtr ns(rabbit::String::create(_sharedstate,s,len));
|
||||
_table(_strings)->newSlot(ns,(int64_t)1);
|
||||
return ns;
|
||||
}
|
||||
|
||||
rabbit::Object SQFuncState::createTable()
|
||||
rabbit::Object FuncState::createTable()
|
||||
{
|
||||
rabbit::ObjectPtr nt(rabbit::Table::create(_sharedstate,0));
|
||||
_table(_strings)->newSlot(nt,(int64_t)1);
|
||||
return nt;
|
||||
}
|
||||
|
||||
SQFunctionProto *SQFuncState::buildProto()
|
||||
rabbit::FunctionProto *FuncState::buildProto()
|
||||
{
|
||||
|
||||
SQFunctionProto *f=SQFunctionProto::create(_ss,_instructions.size(),
|
||||
rabbit::FunctionProto *f=rabbit::FunctionProto::create(_ss,_instructions.size(),
|
||||
_nliterals,_parameters.size(),_functions.size(),_outervalues.size(),
|
||||
_lineinfos.size(),_localvarinfos.size(),_defaultparams.size());
|
||||
|
||||
@ -625,29 +625,29 @@ SQFunctionProto *SQFuncState::buildProto()
|
||||
for(uint64_t ni = 0; ni < _lineinfos.size(); ni++) f->_lineinfos[ni] = _lineinfos[ni];
|
||||
for(uint64_t nd = 0; nd < _defaultparams.size(); nd++) f->_defaultparams[nd] = _defaultparams[nd];
|
||||
|
||||
memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(SQInstruction));
|
||||
memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(rabbit::Instruction));
|
||||
|
||||
f->_varparams = _varparams;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
SQFuncState *SQFuncState::pushChildState(rabbit::SharedState *ss)
|
||||
FuncState *rabbit::FuncState::pushChildState(rabbit::SharedState *ss)
|
||||
{
|
||||
SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState));
|
||||
new (child) SQFuncState(ss,this,_errfunc,_errtarget);
|
||||
FuncState *child = (rabbit::FuncState *)sq_malloc(sizeof(rabbit::FuncState));
|
||||
new (child) FuncState(ss,this,_errfunc,_errtarget);
|
||||
_childstates.pushBack(child);
|
||||
return child;
|
||||
}
|
||||
|
||||
void SQFuncState::popChildState()
|
||||
void FuncState::popChildState()
|
||||
{
|
||||
SQFuncState *child = _childstates.back();
|
||||
sq_delete(child,SQFuncState);
|
||||
FuncState *child = _childstates.back();
|
||||
sq_delete(child,FuncState);
|
||||
_childstates.popBack();
|
||||
}
|
||||
|
||||
SQFuncState::~SQFuncState()
|
||||
FuncState::~rabbit::FuncState()
|
||||
{
|
||||
while(_childstates.size() > 0)
|
||||
{
|
92
rabbit/FuncState.hpp
Normal file
92
rabbit/FuncState.hpp
Normal file
@ -0,0 +1,92 @@
|
||||
/**
|
||||
* @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
|
||||
|
||||
namespace rabbit {
|
||||
class FuncState {
|
||||
public:
|
||||
FuncState(rabbit::SharedState *ss,rabbit::FuncState *parent,compilererrorFunc efunc,void *ed);
|
||||
~FuncState();
|
||||
#ifdef _DEBUG_DUMP
|
||||
void dump(rabbit::FunctionProto *func);
|
||||
#endif
|
||||
void error(const rabbit::Char *err);
|
||||
FuncState *pushChildState(rabbit::SharedState *ss);
|
||||
void popChildState();
|
||||
void addInstruction(SQOpcode _op,int64_t arg0=0,int64_t arg1=0,int64_t arg2=0,int64_t arg3=0){rabbit::Instruction i(_op,arg0,arg1,arg2,arg3);addInstruction(i);}
|
||||
void addInstruction(rabbit::Instruction &i);
|
||||
void setIntructionParams(int64_t pos,int64_t arg0,int64_t arg1,int64_t arg2=0,int64_t arg3=0);
|
||||
void setIntructionParam(int64_t pos,int64_t arg,int64_t val);
|
||||
rabbit::Instruction &getInstruction(int64_t pos){return _instructions[pos];}
|
||||
void popInstructions(int64_t size){for(int64_t i=0;i<size;i++)_instructions.popBack();}
|
||||
void setStacksize(int64_t n);
|
||||
int64_t CountOuters(int64_t stacksize);
|
||||
void snoozeOpt(){_optimization=false;}
|
||||
void addDefaultParam(int64_t trg) { _defaultparams.pushBack(trg); }
|
||||
int64_t getDefaultParamCount() { return _defaultparams.size(); }
|
||||
int64_t getCurrentPos(){return _instructions.size()-1;}
|
||||
int64_t getNumericConstant(const int64_t cons);
|
||||
int64_t getNumericConstant(const float_t cons);
|
||||
int64_t pushLocalVariable(const rabbit::Object &name);
|
||||
void addParameter(const rabbit::Object &name);
|
||||
//void addOuterValue(const rabbit::Object &name);
|
||||
int64_t getLocalVariable(const rabbit::Object &name);
|
||||
void markLocalAsOuter(int64_t pos);
|
||||
int64_t getOuterVariable(const rabbit::Object &name);
|
||||
int64_t generateCode();
|
||||
int64_t getStacksize();
|
||||
int64_t calcStackFramesize();
|
||||
void addLineInfos(int64_t line,bool lineop,bool force=false);
|
||||
rabbit::FunctionProto *buildProto();
|
||||
int64_t allocStackPos();
|
||||
int64_t pushTarget(int64_t n=-1);
|
||||
int64_t popTarget();
|
||||
int64_t topTarget();
|
||||
int64_t getUpTarget(int64_t n);
|
||||
void discardTarget();
|
||||
bool isLocal(uint64_t stkpos);
|
||||
rabbit::Object createString(const rabbit::Char *s,int64_t len = -1);
|
||||
rabbit::Object createTable();
|
||||
bool isConstant(const rabbit::Object &name,rabbit::Object &e);
|
||||
int64_t _returnexp;
|
||||
etk::Vector<rabbit::LocalVarInfo> _vlocals;
|
||||
etk::Vector<int64_t> _targetstack;
|
||||
int64_t _stacksize;
|
||||
bool _varparams;
|
||||
bool _bgenerator;
|
||||
etk::Vector<int64_t> _unresolvedbreaks;
|
||||
etk::Vector<int64_t> _unresolvedcontinues;
|
||||
etk::Vector<rabbit::ObjectPtr> _functions;
|
||||
etk::Vector<rabbit::ObjectPtr> _parameters;
|
||||
etk::Vector<rabbit::OuterVar> _outervalues;
|
||||
rabbit::InstructionVec _instructions;
|
||||
etk::Vector<rabbit::LocalVarInfo> _localvarinfos;
|
||||
rabbit::ObjectPtr _literals;
|
||||
rabbit::ObjectPtr _strings;
|
||||
rabbit::ObjectPtr _name;
|
||||
rabbit::ObjectPtr _sourcename;
|
||||
int64_t _nliterals;
|
||||
etk::Vector<rabbit::LineInfo> _lineinfos;
|
||||
FuncState *_parent;
|
||||
etk::Vector<int64_t> _scope_blocks;
|
||||
etk::Vector<int64_t> _breaktargets;
|
||||
etk::Vector<int64_t> _continuetargets;
|
||||
etk::Vector<int64_t> _defaultparams;
|
||||
int64_t _lastline;
|
||||
int64_t _traps; //contains number of nested exception traps
|
||||
int64_t _outers;
|
||||
bool _optimization;
|
||||
rabbit::SharedState *_sharedstate;
|
||||
etk::Vector<FuncState*> _childstates;
|
||||
int64_t getConstant(const rabbit::Object &cons);
|
||||
private:
|
||||
compilererrorFunc _errfunc;
|
||||
void *_errtarget;
|
||||
rabbit::SharedState *_ss;
|
||||
};
|
||||
}
|
224
rabbit/FunctionProto.cpp
Normal file
224
rabbit/FunctionProto.cpp
Normal file
@ -0,0 +1,224 @@
|
||||
/**
|
||||
* @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/FunctionProto.hpp>
|
||||
|
||||
|
||||
const rabbit::Char* rabbit::FunctionProto::getLocal(rabbit::VirtualMachine *vm,uint64_t stackbase,uint64_t nseq,uint64_t nop)
|
||||
{
|
||||
uint64_t nvars=_nlocalvarinfos;
|
||||
const rabbit::Char *res=NULL;
|
||||
if(nvars>=nseq){
|
||||
for(uint64_t i=0;i<nvars;i++){
|
||||
if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop)
|
||||
{
|
||||
if(nseq==0){
|
||||
vm->push(vm->_stack[stackbase+_localvarinfos[i]._pos]);
|
||||
res=_stringval(_localvarinfos[i]._name);
|
||||
break;
|
||||
}
|
||||
nseq--;
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int64_t rabbit::FunctionProto::getLine(rabbit::Instruction *curr)
|
||||
{
|
||||
int64_t op = (int64_t)(curr-_instructions);
|
||||
int64_t line=_lineinfos[0]._line;
|
||||
int64_t low = 0;
|
||||
int64_t high = _nlineinfos - 1;
|
||||
int64_t mid = 0;
|
||||
while(low <= high)
|
||||
{
|
||||
mid = low + ((high - low) >> 1);
|
||||
int64_t curop = _lineinfos[mid]._op;
|
||||
if(curop > op)
|
||||
{
|
||||
high = mid - 1;
|
||||
}
|
||||
else if(curop < op) {
|
||||
if(mid < (_nlineinfos - 1)
|
||||
&& _lineinfos[mid + 1]._op >= op) {
|
||||
break;
|
||||
}
|
||||
low = mid + 1;
|
||||
}
|
||||
else { //equal
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while(mid > 0 && _lineinfos[mid]._op >= op) mid--;
|
||||
|
||||
line = _lineinfos[mid]._line;
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
|
||||
rabbit::FunctionProto::FunctionProto(rabbit::SharedState *ss)
|
||||
{
|
||||
_stacksize=0;
|
||||
_bgenerator=false;
|
||||
}
|
||||
|
||||
rabbit::FunctionProto::~FunctionProto()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool rabbit::FunctionProto::save(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQWRITEFUNC write)
|
||||
{
|
||||
int64_t i,nliterals = _nliterals,nparameters = _nparameters;
|
||||
int64_t noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos;
|
||||
int64_t nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions;
|
||||
int64_t ndefaultparams = _ndefaultparams;
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
|
||||
_CHECK_IO(WriteObject(v,up,write,_sourcename));
|
||||
_CHECK_IO(WriteObject(v,up,write,_name));
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&nliterals,sizeof(nliterals)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&nparameters,sizeof(nparameters)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&ndefaultparams,sizeof(ndefaultparams)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions)));
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
|
||||
for(i=0;i<nliterals;i++){
|
||||
_CHECK_IO(WriteObject(v,up,write,_literals[i]));
|
||||
}
|
||||
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
|
||||
for(i=0;i<nparameters;i++){
|
||||
_CHECK_IO(WriteObject(v,up,write,_parameters[i]));
|
||||
}
|
||||
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
|
||||
for(i=0;i<noutervalues;i++){
|
||||
_CHECK_IO(SafeWrite(v,write,up,&_outervalues[i]._type,sizeof(uint64_t)));
|
||||
_CHECK_IO(WriteObject(v,up,write,_outervalues[i]._src));
|
||||
_CHECK_IO(WriteObject(v,up,write,_outervalues[i]._name));
|
||||
}
|
||||
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
|
||||
for(i=0;i<nlocalvarinfos;i++){
|
||||
rabbit::LocalVarInfo &lvi=_localvarinfos[i];
|
||||
_CHECK_IO(WriteObject(v,up,write,lvi._name));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&lvi._pos,sizeof(uint64_t)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&lvi._start_op,sizeof(uint64_t)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&lvi._end_op,sizeof(uint64_t)));
|
||||
}
|
||||
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
|
||||
_CHECK_IO(SafeWrite(v,write,up,_lineinfos,sizeof(rabbit::LineInfo)*nlineinfos));
|
||||
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
|
||||
_CHECK_IO(SafeWrite(v,write,up,_defaultparams,sizeof(int64_t)*ndefaultparams));
|
||||
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
|
||||
_CHECK_IO(SafeWrite(v,write,up,_instructions,sizeof(rabbit::Instruction)*ninstructions));
|
||||
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
|
||||
for(i=0;i<nfunctions;i++){
|
||||
_CHECK_IO(_funcproto(_functions[i])->save(v,up,write));
|
||||
}
|
||||
_CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams)));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rabbit::FunctionProto::load(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQREADFUNC read,rabbit::ObjectPtr &ret)
|
||||
{
|
||||
int64_t i, nliterals,nparameters;
|
||||
int64_t noutervalues ,nlocalvarinfos ;
|
||||
int64_t nlineinfos,ninstructions ,nfunctions,ndefaultparams ;
|
||||
rabbit::ObjectPtr sourcename, name;
|
||||
rabbit::ObjectPtr o;
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
|
||||
_CHECK_IO(ReadObject(v, up, read, sourcename));
|
||||
_CHECK_IO(ReadObject(v, up, read, name));
|
||||
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
|
||||
_CHECK_IO(SafeRead(v,read,up, &nliterals, sizeof(nliterals)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &nparameters, sizeof(nparameters)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &noutervalues, sizeof(noutervalues)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &nlocalvarinfos, sizeof(nlocalvarinfos)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &nlineinfos, sizeof(nlineinfos)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &ndefaultparams, sizeof(ndefaultparams)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &ninstructions, sizeof(ninstructions)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions)));
|
||||
|
||||
|
||||
rabbit::FunctionProto *f = rabbit::FunctionProto::create(NULL,ninstructions,nliterals,nparameters,
|
||||
nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams);
|
||||
rabbit::ObjectPtr proto = f; //gets a ref in case of failure
|
||||
f->_sourcename = sourcename;
|
||||
f->_name = name;
|
||||
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
|
||||
|
||||
for(i = 0;i < nliterals; i++){
|
||||
_CHECK_IO(ReadObject(v, up, read, o));
|
||||
f->_literals[i] = o;
|
||||
}
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
|
||||
|
||||
for(i = 0; i < nparameters; i++){
|
||||
_CHECK_IO(ReadObject(v, up, read, o));
|
||||
f->_parameters[i] = o;
|
||||
}
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
|
||||
|
||||
for(i = 0; i < noutervalues; i++){
|
||||
uint64_t type;
|
||||
rabbit::ObjectPtr name;
|
||||
_CHECK_IO(SafeRead(v,read,up, &type, sizeof(uint64_t)));
|
||||
_CHECK_IO(ReadObject(v, up, read, o));
|
||||
_CHECK_IO(ReadObject(v, up, read, name));
|
||||
f->_outervalues[i] = rabbit::OuterVar(name,o, (rabbit::OuterType)type);
|
||||
}
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
|
||||
|
||||
for(i = 0; i < nlocalvarinfos; i++){
|
||||
rabbit::LocalVarInfo lvi;
|
||||
_CHECK_IO(ReadObject(v, up, read, lvi._name));
|
||||
_CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(uint64_t)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(uint64_t)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(uint64_t)));
|
||||
f->_localvarinfos[i] = lvi;
|
||||
}
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
|
||||
_CHECK_IO(SafeRead(v,read,up, f->_lineinfos, sizeof(rabbit::LineInfo)*nlineinfos));
|
||||
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
|
||||
_CHECK_IO(SafeRead(v,read,up, f->_defaultparams, sizeof(int64_t)*ndefaultparams));
|
||||
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
|
||||
_CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(rabbit::Instruction)*ninstructions));
|
||||
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
|
||||
for(i = 0; i < nfunctions; i++){
|
||||
_CHECK_IO(_funcproto(o)->load(v, up, read, o));
|
||||
f->_functions[i] = o;
|
||||
}
|
||||
_CHECK_IO(SafeRead(v,read,up, &f->_stacksize, sizeof(f->_stacksize)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &f->_bgenerator, sizeof(f->_bgenerator)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &f->_varparams, sizeof(f->_varparams)));
|
||||
|
||||
ret = f;
|
||||
return true;
|
||||
}
|
||||
|
105
rabbit/FunctionProto.hpp
Normal file
105
rabbit/FunctionProto.hpp
Normal file
@ -0,0 +1,105 @@
|
||||
/**
|
||||
* @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
|
||||
|
||||
namespace rabbit {
|
||||
|
||||
#define _FUNC_SIZE(ni,nl,nparams,nfuncs,nouters,nlineinf,localinf,defparams) (sizeof(rabbit::FunctionProto) \
|
||||
+((ni-1)*sizeof(rabbit::Instruction))+(nl*sizeof(rabbit::ObjectPtr)) \
|
||||
+(nparams*sizeof(rabbit::ObjectPtr))+(nfuncs*sizeof(rabbit::ObjectPtr)) \
|
||||
+(nouters*sizeof(rabbit::OuterVar))+(nlineinf*sizeof(rabbit::LineInfo)) \
|
||||
+(localinf*sizeof(rabbit::LocalVarInfo))+(defparams*sizeof(int64_t)))
|
||||
|
||||
|
||||
class FunctionProto : public rabbit::RefCounted {
|
||||
private:
|
||||
FunctionProto(rabbit::SharedState *ss);
|
||||
~FunctionProto();
|
||||
|
||||
public:
|
||||
static rabbit::FunctionProto *create(rabbit::SharedState *ss,int64_t ninstructions,
|
||||
int64_t nliterals,int64_t nparameters,
|
||||
int64_t nfunctions,int64_t noutervalues,
|
||||
int64_t nlineinfos,int64_t nlocalvarinfos,int64_t ndefaultparams)
|
||||
{
|
||||
rabbit::FunctionProto *f;
|
||||
//I compact the whole class and members in a single memory allocation
|
||||
f = (rabbit::FunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams));
|
||||
new (f) rabbit::FunctionProto(ss);
|
||||
f->_ninstructions = ninstructions;
|
||||
f->_literals = (rabbit::ObjectPtr*)&f->_instructions[ninstructions];
|
||||
f->_nliterals = nliterals;
|
||||
f->_parameters = (rabbit::ObjectPtr*)&f->_literals[nliterals];
|
||||
f->_nparameters = nparameters;
|
||||
f->_functions = (rabbit::ObjectPtr*)&f->_parameters[nparameters];
|
||||
f->_nfunctions = nfunctions;
|
||||
f->_outervalues = (rabbit::OuterVar*)&f->_functions[nfunctions];
|
||||
f->_noutervalues = noutervalues;
|
||||
f->_lineinfos = (rabbit::LineInfo *)&f->_outervalues[noutervalues];
|
||||
f->_nlineinfos = nlineinfos;
|
||||
f->_localvarinfos = (rabbit::LocalVarInfo *)&f->_lineinfos[nlineinfos];
|
||||
f->_nlocalvarinfos = nlocalvarinfos;
|
||||
f->_defaultparams = (int64_t *)&f->_localvarinfos[nlocalvarinfos];
|
||||
f->_ndefaultparams = ndefaultparams;
|
||||
|
||||
_CONSTRUCT_VECTOR(rabbit::ObjectPtr,f->_nliterals,f->_literals);
|
||||
_CONSTRUCT_VECTOR(rabbit::ObjectPtr,f->_nparameters,f->_parameters);
|
||||
_CONSTRUCT_VECTOR(rabbit::ObjectPtr,f->_nfunctions,f->_functions);
|
||||
_CONSTRUCT_VECTOR(rabbit::OuterVar,f->_noutervalues,f->_outervalues);
|
||||
//_CONSTRUCT_VECTOR(rabbit::LineInfo,f->_nlineinfos,f->_lineinfos); //not required are 2 integers
|
||||
_CONSTRUCT_VECTOR(rabbit::LocalVarInfo,f->_nlocalvarinfos,f->_localvarinfos);
|
||||
return f;
|
||||
}
|
||||
void release(){
|
||||
_DESTRUCT_VECTOR(ObjectPtr,_nliterals,_literals);
|
||||
_DESTRUCT_VECTOR(ObjectPtr,_nparameters,_parameters);
|
||||
_DESTRUCT_VECTOR(ObjectPtr,_nfunctions,_functions);
|
||||
_DESTRUCT_VECTOR(rabbit::OuterVar,_noutervalues,_outervalues);
|
||||
//_DESTRUCT_VECTOR(rabbit::LineInfo,_nlineinfos,_lineinfos); //not required are 2 integers
|
||||
_DESTRUCT_VECTOR(rabbit::LocalVarInfo,_nlocalvarinfos,_localvarinfos);
|
||||
int64_t size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos,_ndefaultparams);
|
||||
this->~rabbit::FunctionProto();
|
||||
sq_vm_free(this,size);
|
||||
}
|
||||
|
||||
const rabbit::Char* getLocal(rabbit::VirtualMachine *v,uint64_t stackbase,uint64_t nseq,uint64_t nop);
|
||||
int64_t getLine(rabbit::Instruction *curr);
|
||||
bool save(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQWRITEFUNC write);
|
||||
static bool load(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQREADFUNC read,rabbit::ObjectPtr &ret);
|
||||
rabbit::ObjectPtr _sourcename;
|
||||
rabbit::ObjectPtr _name;
|
||||
int64_t _stacksize;
|
||||
bool _bgenerator;
|
||||
int64_t _varparams;
|
||||
|
||||
int64_t _nlocalvarinfos;
|
||||
rabbit::LocalVarInfo *_localvarinfos;
|
||||
|
||||
int64_t _nlineinfos;
|
||||
rabbit::LineInfo *_lineinfos;
|
||||
|
||||
int64_t _nliterals;
|
||||
rabbit::ObjectPtr *_literals;
|
||||
|
||||
int64_t _nparameters;
|
||||
rabbit::ObjectPtr *_parameters;
|
||||
|
||||
int64_t _nfunctions;
|
||||
rabbit::ObjectPtr *_functions;
|
||||
|
||||
int64_t _noutervalues;
|
||||
rabbit::OuterVar *_outervalues;
|
||||
|
||||
int64_t _ndefaultparams;
|
||||
int64_t *_defaultparams;
|
||||
|
||||
int64_t _ninstructions;
|
||||
rabbit::Instruction _instructions[1];
|
||||
};
|
||||
|
||||
}
|
87
rabbit/Generator.cpp
Normal file
87
rabbit/Generator.cpp
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)
|
||||
*/
|
||||
#include <rabbit/Generator.hpp>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool rabbit::Generator::yield(rabbit::VirtualMachine *v,int64_t target)
|
||||
{
|
||||
if(_state==eSuspended) { v->raise_error(_SC("internal vm error, yielding dead generator")); return false;}
|
||||
if(_state==eDead) { v->raise_error(_SC("internal vm error, yielding a dead generator")); return false; }
|
||||
int64_t size = v->_top-v->_stackbase;
|
||||
|
||||
_stack.resize(size);
|
||||
rabbit::Object _this = v->_stack[v->_stackbase];
|
||||
_stack[0] = ISREFCOUNTED(sq_type(_this)) ? rabbit::ObjectPtr(_refcounted(_this)->getWeakRef(sq_type(_this))) : _this;
|
||||
for(int64_t n =1; n<target; n++) {
|
||||
_stack[n] = v->_stack[v->_stackbase+n];
|
||||
}
|
||||
for(int64_t j =0; j < size; j++)
|
||||
{
|
||||
v->_stack[v->_stackbase+j].Null();
|
||||
}
|
||||
|
||||
_ci = *v->ci;
|
||||
_ci._generator=NULL;
|
||||
for(int64_t i=0;i<_ci._etraps;i++) {
|
||||
_etraps.pushBack(v->_etraps.back());
|
||||
v->_etraps.popBack();
|
||||
// store relative stack base and size in case of resume to other _top
|
||||
rabbit::ExceptionTrap &et = _etraps.back();
|
||||
et._stackbase -= v->_stackbase;
|
||||
et._stacksize -= v->_stackbase;
|
||||
}
|
||||
_state=eSuspended;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rabbit::Generator::resume(rabbit::VirtualMachine *v,rabbit::ObjectPtr &dest)
|
||||
{
|
||||
if(_state==eDead){ v->raise_error(_SC("resuming dead generator")); return false; }
|
||||
if(_state==eRunning){ v->raise_error(_SC("resuming active generator")); return false; }
|
||||
int64_t size = _stack.size();
|
||||
int64_t target = &dest - &(v->_stack[v->_stackbase]);
|
||||
assert(target>=0 && target<=255);
|
||||
int64_t newbase = v->_top;
|
||||
if(!v->enterFrame(v->_top, v->_top + size, false))
|
||||
return false;
|
||||
v->ci->_generator = this;
|
||||
v->ci->_target = (int32_t)target;
|
||||
v->ci->_closure = _ci._closure;
|
||||
v->ci->_ip = _ci._ip;
|
||||
v->ci->_literals = _ci._literals;
|
||||
v->ci->_ncalls = _ci._ncalls;
|
||||
v->ci->_etraps = _ci._etraps;
|
||||
v->ci->_root = _ci._root;
|
||||
|
||||
|
||||
for(int64_t i=0;i<_ci._etraps;i++) {
|
||||
v->_etraps.pushBack(_etraps.back());
|
||||
_etraps.popBack();
|
||||
rabbit::ExceptionTrap &et = v->_etraps.back();
|
||||
// restore absolute stack base and size
|
||||
et._stackbase += newbase;
|
||||
et._stacksize += newbase;
|
||||
}
|
||||
rabbit::Object _this = _stack[0];
|
||||
v->_stack[v->_stackbase] = sq_type(_this) == rabbit::OT_WEAKREF ? _weakref(_this)->_obj : _this;
|
||||
|
||||
for(int64_t n = 1; n<size; n++) {
|
||||
v->_stack[v->_stackbase+n] = _stack[n];
|
||||
_stack[n].Null();
|
||||
}
|
||||
|
||||
_state=eRunning;
|
||||
if (v->_debughook)
|
||||
v->callDebugHook(_SC('c'));
|
||||
|
||||
return true;
|
||||
}
|
47
rabbit/Generator.hpp
Normal file
47
rabbit/Generator.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @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
|
||||
|
||||
namespace rabbit {
|
||||
class Generator : public rabbit::RefCounted {
|
||||
public:
|
||||
enum rabbit::GeneratorState{eRunning,eSuspended,eDead};
|
||||
private:
|
||||
rabbit::Generator(rabbit::SharedState *ss,rabbit::Closure *closure){
|
||||
_closure=closure;
|
||||
_state=eRunning;
|
||||
_ci._generator=NULL;
|
||||
}
|
||||
public:
|
||||
static rabbit::Generator *create(rabbit::SharedState *ss,rabbit::Closure *closure){
|
||||
rabbit::Generator *nc=(rabbit::Generator*)SQ_MALLOC(sizeof(rabbit::Generator));
|
||||
new (nc) rabbit::Generator(ss,closure);
|
||||
return nc;
|
||||
}
|
||||
~rabbit::Generator()
|
||||
{
|
||||
|
||||
}
|
||||
void kill(){
|
||||
_state=eDead;
|
||||
_stack.resize(0);
|
||||
_closure.Null();}
|
||||
void release(){
|
||||
sq_delete(this,rabbit::Generator);
|
||||
}
|
||||
|
||||
bool yield(rabbit::VirtualMachine *v,int64_t target);
|
||||
bool resume(rabbit::VirtualMachine *v,rabbit::ObjectPtr &dest);
|
||||
rabbit::ObjectPtr _closure;
|
||||
etk::Vector<rabbit::ObjectPtr> _stack;
|
||||
rabbit::VirtualMachine::callInfo _ci;
|
||||
etk::Vector<rabbit::ExceptionTrap> _etraps;
|
||||
rabbit::GeneratorState _state;
|
||||
};
|
||||
|
||||
}
|
9
rabbit/Instruction.cpp
Normal file
9
rabbit/Instruction.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/Instruction.hpp>
|
||||
|
12
rabbit/Instruction.hpp
Normal file
12
rabbit/Instruction.hpp
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* @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
|
||||
|
||||
namespace rabbit {
|
||||
|
||||
}
|
@ -5,10 +5,7 @@
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
|
||||
#include <rabbit/sqpcheader.hpp>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <rabbit/Lexer.hpp>
|
||||
|
||||
|
||||
#include <rabbit/sqcompiler.hpp>
|
||||
@ -23,13 +20,13 @@
|
||||
#define TERMINATE_BUFFER() {_longstr.pushBack(_SC('\0'));}
|
||||
#define ADD_KEYWORD(key,id) _keywords->newSlot( rabbit::String::create(ss, _SC(#key)) ,int64_t(id))
|
||||
|
||||
SQLexer::SQLexer(){}
|
||||
SQLexer::~SQLexer()
|
||||
rabbit::Lexer::Lexer(){}
|
||||
rabbit::Lexer::~Lexer()
|
||||
{
|
||||
_keywords->release();
|
||||
}
|
||||
|
||||
void SQLexer::init(rabbit::SharedState *ss, SQLEXREADFUNC rg, rabbit::UserPointer up,compilererrorFunc efunc,void *ed)
|
||||
void rabbit::Lexer::init(rabbit::SharedState *ss, SQLEXREADFUNC rg, rabbit::UserPointer up,compilererrorFunc efunc,void *ed)
|
||||
{
|
||||
_errfunc = efunc;
|
||||
_errtarget = ed;
|
||||
@ -84,12 +81,12 @@ void SQLexer::init(rabbit::SharedState *ss, SQLEXREADFUNC rg, rabbit::UserPointe
|
||||
next();
|
||||
}
|
||||
|
||||
void SQLexer::error(const rabbit::Char *err)
|
||||
void rabbit::Lexer::error(const rabbit::Char *err)
|
||||
{
|
||||
_errfunc(_errtarget,err);
|
||||
}
|
||||
|
||||
void SQLexer::next()
|
||||
void rabbit::Lexer::next()
|
||||
{
|
||||
int64_t t = _readf(_up);
|
||||
if(t > MAX_CHAR) error(_SC("Invalid character"));
|
||||
@ -101,7 +98,7 @@ void SQLexer::next()
|
||||
_reached_eof = SQTrue;
|
||||
}
|
||||
|
||||
const rabbit::Char *SQLexer::tok2Str(int64_t tok)
|
||||
const rabbit::Char *rabbit::Lexer::tok2Str(int64_t tok)
|
||||
{
|
||||
rabbit::ObjectPtr itr, key, val;
|
||||
int64_t nitr;
|
||||
@ -113,7 +110,7 @@ const rabbit::Char *SQLexer::tok2Str(int64_t tok)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SQLexer::lexBlockComment()
|
||||
void rabbit::Lexer::lexBlockComment()
|
||||
{
|
||||
bool done = false;
|
||||
while(!done) {
|
||||
@ -125,12 +122,12 @@ void SQLexer::lexBlockComment()
|
||||
}
|
||||
}
|
||||
}
|
||||
void SQLexer::lexLineComment()
|
||||
void rabbit::Lexer::lexLineComment()
|
||||
{
|
||||
do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB()));
|
||||
}
|
||||
|
||||
int64_t SQLexer::Lex()
|
||||
int64_t rabbit::Lexer::Lex()
|
||||
{
|
||||
_lasttokenline = _currentline;
|
||||
while(CUR_CHAR != RABBIT_EOB) {
|
||||
@ -285,7 +282,7 @@ int64_t SQLexer::Lex()
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t SQLexer::getIDType(const rabbit::Char *s,int64_t len)
|
||||
int64_t rabbit::Lexer::getIDType(const rabbit::Char *s,int64_t len)
|
||||
{
|
||||
rabbit::ObjectPtr t;
|
||||
if(_keywords->getStr(s,len, t)) {
|
||||
@ -296,7 +293,7 @@ int64_t SQLexer::getIDType(const rabbit::Char *s,int64_t len)
|
||||
|
||||
#ifdef SQUNICODE
|
||||
#if WCHAR_SIZE == 2
|
||||
int64_t SQLexer::addUTF16(uint64_t ch)
|
||||
int64_t rabbit::Lexer::addUTF16(uint64_t ch)
|
||||
{
|
||||
if (ch >= 0x10000)
|
||||
{
|
||||
@ -312,7 +309,7 @@ int64_t SQLexer::addUTF16(uint64_t ch)
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
int64_t SQLexer::addUTF8(uint64_t ch)
|
||||
int64_t rabbit::Lexer::addUTF8(uint64_t ch)
|
||||
{
|
||||
if (ch < 0x80) {
|
||||
APPEND_CHAR((char)ch);
|
||||
@ -340,7 +337,7 @@ int64_t SQLexer::addUTF8(uint64_t ch)
|
||||
}
|
||||
#endif
|
||||
|
||||
int64_t SQLexer::processStringHexEscape(rabbit::Char *dest, int64_t maxdigits)
|
||||
int64_t rabbit::Lexer::processStringHexEscape(rabbit::Char *dest, int64_t maxdigits)
|
||||
{
|
||||
NEXT();
|
||||
if (!isxdigit(CUR_CHAR)) error(_SC("hexadecimal number expected"));
|
||||
@ -354,7 +351,7 @@ int64_t SQLexer::processStringHexEscape(rabbit::Char *dest, int64_t maxdigits)
|
||||
return n;
|
||||
}
|
||||
|
||||
int64_t SQLexer::readString(int64_t ndelim,bool verbatim)
|
||||
int64_t rabbit::Lexer::readString(int64_t ndelim,bool verbatim)
|
||||
{
|
||||
INIT_TEMP_STRING();
|
||||
NEXT();
|
||||
@ -482,7 +479,7 @@ int64_t isexponent(int64_t c) { return c == 'e' || c=='E'; }
|
||||
|
||||
|
||||
#define MAX_HEX_DIGITS (sizeof(int64_t)*2)
|
||||
int64_t SQLexer::readNumber()
|
||||
int64_t rabbit::Lexer::readNumber()
|
||||
{
|
||||
#define TINT 1
|
||||
#define TFLOAT 2
|
||||
@ -551,7 +548,7 @@ int64_t SQLexer::readNumber()
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t SQLexer::readId()
|
||||
int64_t rabbit::Lexer::readId()
|
||||
{
|
||||
int64_t res;
|
||||
INIT_TEMP_STRING();
|
61
rabbit/Lexer.hpp
Normal file
61
rabbit/Lexer.hpp
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* @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
|
||||
|
||||
namespace rabbit {
|
||||
|
||||
#ifdef SQUNICODE
|
||||
typedef Char LexChar;
|
||||
#else
|
||||
typedef unsigned char LexChar;
|
||||
#endif
|
||||
|
||||
class Lexer {
|
||||
public:
|
||||
Lexer();
|
||||
~Lexer();
|
||||
void init(SharedState *ss,SQLEXREADFUNC rg,UserPointer up,compilererrorFunc efunc,void *ed);
|
||||
void error(const Char *err);
|
||||
int64_t Lex();
|
||||
const Char *tok2Str(int64_t tok);
|
||||
private:
|
||||
int64_t getIDType(const Char *s,int64_t len);
|
||||
int64_t readString(int64_t ndelim,bool verbatim);
|
||||
int64_t readNumber();
|
||||
void lexBlockComment();
|
||||
void lexLineComment();
|
||||
int64_t readId();
|
||||
void next();
|
||||
#ifdef SQUNICODE
|
||||
#if WCHAR_SIZE == 2
|
||||
int64_t addUTF16(uint64_t ch);
|
||||
#endif
|
||||
#else
|
||||
int64_t addUTF8(uint64_t ch);
|
||||
#endif
|
||||
int64_t processStringHexEscape(Char *dest, int64_t maxdigits);
|
||||
int64_t _curtoken;
|
||||
Table *_keywords;
|
||||
Bool _reached_eof;
|
||||
public:
|
||||
int64_t _prevtoken;
|
||||
int64_t _currentline;
|
||||
int64_t _lasttokenline;
|
||||
int64_t _currentcolumn;
|
||||
const Char *_svalue;
|
||||
int64_t _nvalue;
|
||||
float_t _fvalue;
|
||||
SQLEXREADFUNC _readf;
|
||||
UserPointer _up;
|
||||
LexChar _currdata;
|
||||
SharedState *_sharedstate;
|
||||
etk::Vector<Char> _longstr;
|
||||
compilererrorFunc _errfunc;
|
||||
void *_errtarget;
|
||||
};
|
||||
}
|
9
rabbit/LineInfo.cpp
Normal file
9
rabbit/LineInfo.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/LineInfo.hpp>
|
||||
|
16
rabbit/LineInfo.hpp
Normal file
16
rabbit/LineInfo.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* @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
|
||||
|
||||
namespace rabbit {
|
||||
class LineInfo {
|
||||
public:
|
||||
int64_t _line;
|
||||
int64_t _op;
|
||||
};
|
||||
}
|
9
rabbit/LocalVarInfo.cpp
Normal file
9
rabbit/LocalVarInfo.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/LocalVarInfo.hpp>
|
||||
|
26
rabbit/LocalVarInfo.hpp
Normal file
26
rabbit/LocalVarInfo.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* @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
|
||||
|
||||
namespace rabbit {
|
||||
|
||||
class LocalVarInfo {
|
||||
public:
|
||||
LocalVarInfo():_start_op(0),_end_op(0),_pos(0){}
|
||||
LocalVarInfo(const LocalVarInfo &lvi) {
|
||||
_name=lvi._name;
|
||||
_start_op=lvi._start_op;
|
||||
_end_op=lvi._end_op;
|
||||
_pos=lvi._pos;
|
||||
}
|
||||
rabbit::ObjectPtr _name;
|
||||
uint64_t _start_op;
|
||||
uint64_t _end_op;
|
||||
uint64_t _pos;
|
||||
};
|
||||
}
|
9
rabbit/NativeClosure.cpp
Normal file
9
rabbit/NativeClosure.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/NativeClosure.hpp>
|
||||
|
63
rabbit/NativeClosure.hpp
Normal file
63
rabbit/NativeClosure.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @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 {
|
||||
#define _CALC_NATVIVECLOSURE_SIZE(noutervalues) (sizeof(rabbit::NativeClosure) + (noutervalues*sizeof(rabbit::ObjectPtr)))
|
||||
class NativeClosure : public rabbit::RefCounted {
|
||||
private:
|
||||
rabbit::NativeClosure(rabbit::SharedState *ss,SQFUNCTION func){
|
||||
_function=func;
|
||||
_env = NULL;
|
||||
}
|
||||
public:
|
||||
static rabbit::NativeClosure *create(rabbit::SharedState *ss,SQFUNCTION func,int64_t nouters)
|
||||
{
|
||||
int64_t size = _CALC_NATVIVECLOSURE_SIZE(nouters);
|
||||
rabbit::NativeClosure *nc=(rabbit::NativeClosure*)SQ_MALLOC(size);
|
||||
new (nc) rabbit::NativeClosure(ss,func);
|
||||
nc->_outervalues = (rabbit::ObjectPtr *)(nc + 1);
|
||||
nc->_noutervalues = nouters;
|
||||
_CONSTRUCT_VECTOR(rabbit::ObjectPtr,nc->_noutervalues,nc->_outervalues);
|
||||
return nc;
|
||||
}
|
||||
rabbit::NativeClosure *clone()
|
||||
{
|
||||
rabbit::NativeClosure * ret = rabbit::NativeClosure::create(NULL,_function,_noutervalues);
|
||||
ret->_env = _env;
|
||||
if(ret->_env) __ObjaddRef(ret->_env);
|
||||
ret->_name = _name;
|
||||
_COPY_VECTOR(ret->_outervalues,_outervalues,_noutervalues);
|
||||
ret->_typecheck = _typecheck;
|
||||
ret->_nparamscheck = _nparamscheck;
|
||||
return ret;
|
||||
}
|
||||
~rabbit::NativeClosure()
|
||||
{
|
||||
__Objrelease(_env);
|
||||
}
|
||||
void release(){
|
||||
int64_t size = _CALC_NATVIVECLOSURE_SIZE(_noutervalues);
|
||||
_DESTRUCT_VECTOR(ObjectPtr,_noutervalues,_outervalues);
|
||||
this->~rabbit::NativeClosure();
|
||||
sq_free(this,size);
|
||||
}
|
||||
|
||||
int64_t _nparamscheck;
|
||||
etk::Vector<int64_t> _typecheck;
|
||||
rabbit::ObjectPtr *_outervalues;
|
||||
uint64_t _noutervalues;
|
||||
rabbit::WeakRef *_env;
|
||||
SQFUNCTION _function;
|
||||
rabbit::ObjectPtr _name;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -53,15 +53,15 @@ RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_TABLE, rabbit::Table, pTable)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_CLASS, rabbit::Class, pClass)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_INSTANCE, rabbit::Instance, pInstance)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_ARRAY, rabbit::Array, pArray)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_CLOSURE, SQClosure, pClosure)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_NATIVECLOSURE, SQNativeClosure, pNativeClosure)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_OUTER, SQOuter, pOuter)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_GENERATOR, SQGenerator, pGenerator)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_CLOSURE, rabbit::Closure, pClosure)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_NATIVECLOSURE, rabbit::NativeClosure, pNativeClosure)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_OUTER, rabbit::Outer, pOuter)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_GENERATOR, rabbit::Generator, pGenerator)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_STRING, rabbit::String, pString)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_USERDATA, rabbit::UserData, pUserData)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_WEAKREF, rabbit::WeakRef, pWeakRef)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_THREAD, rabbit::VirtualMachine, pThread)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_FUNCPROTO, SQFunctionProto, pFunctionProto)
|
||||
RABBIT_OBJ_REF_TYPE_INSTANCIATE(rabbit::OT_FUNCPROTO, rabbit::FunctionProto, pFunctionProto)
|
||||
|
||||
RABBIT_SCALAR_TYPE_INSTANCIATE(rabbit::OT_INTEGER, int64_t, nInteger)
|
||||
RABBIT_SCALAR_TYPE_INSTANCIATE(rabbit::OT_FLOAT, float_t, fFloat)
|
||||
|
@ -37,15 +37,15 @@ namespace rabbit {
|
||||
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)
|
||||
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_CLOSURE, rabbit::Closure, pClosure)
|
||||
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_NATIVECLOSURE, rabbit::NativeClosure, pNativeClosure)
|
||||
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_OUTER, rabbit::Outer, pOuter)
|
||||
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_GENERATOR, rabbit::Generator, pGenerator)
|
||||
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_STRING, rabbit::String, pString)
|
||||
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_USERDATA, UserData, pUserData)
|
||||
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_WEAKREF, WeakRef, pWeakRef)
|
||||
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_THREAD, VirtualMachine, pThread)
|
||||
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_FUNCPROTO, SQFunctionProto, pFunctionProto)
|
||||
RABBIT_OBJ_REF_TYPE_DECLARE(rabbit::OT_FUNCPROTO, rabbit::FunctionProto, pFunctionProto)
|
||||
|
||||
RABBIT_SCALAR_TYPE_DECLARE(rabbit::OT_INTEGER, int64_t, nInteger)
|
||||
RABBIT_SCALAR_TYPE_DECLARE(rabbit::OT_FLOAT, float_t, fFloat)
|
||||
|
@ -13,13 +13,13 @@
|
||||
namespace rabbit {
|
||||
|
||||
union ObjectValue {
|
||||
struct SQClosure *pClosure;
|
||||
struct SQOuter *pOuter;
|
||||
struct SQGenerator *pGenerator;
|
||||
struct SQNativeClosure *pNativeClosure;
|
||||
struct rabbit::Closure *pClosure;
|
||||
struct rabbit::Outer *pOuter;
|
||||
struct rabbit::Generator *pGenerator;
|
||||
struct rabbit::NativeClosure *pNativeClosure;
|
||||
int64_t nInteger;
|
||||
float_t fFloat;
|
||||
struct SQFunctionProto *pFunctionProto;
|
||||
struct rabbit::FunctionProto *pFunctionProto;
|
||||
|
||||
rabbit::Table* pTable;
|
||||
rabbit::String* pString;
|
||||
|
9
rabbit/Outer.cpp
Normal file
9
rabbit/Outer.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/Outer.hpp>
|
||||
|
37
rabbit/Outer.hpp
Normal file
37
rabbit/Outer.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
|
||||
|
||||
namespace rabbit {
|
||||
class Outer : public rabbit::RefCounted {
|
||||
private:
|
||||
rabbit::Outer(rabbit::SharedState *ss, rabbit::ObjectPtr *outer){
|
||||
_valptr = outer;
|
||||
_next = NULL;
|
||||
}
|
||||
public:
|
||||
static rabbit::Outer *create(rabbit::SharedState *ss, rabbit::ObjectPtr *outer) {
|
||||
rabbit::Outer *nc = (rabbit::Outer*)SQ_MALLOC(sizeof(rabbit::Outer));
|
||||
new (nc) rabbit::Outer(ss, outer);
|
||||
return nc;
|
||||
}
|
||||
~Outer() {
|
||||
|
||||
}
|
||||
void release()
|
||||
{
|
||||
this->~rabbit::Outer();
|
||||
sq_vm_free(this,sizeof(rabbit::Outer));
|
||||
}
|
||||
rabbit::ObjectPtr *_valptr; /* pointer to value on stack, or _value below */
|
||||
int64_t _idx; /* idx in stack array, for relocation */
|
||||
rabbit::ObjectPtr _value; /* value of outer after stack frame is closed */
|
||||
rabbit::Outer *_next; /* pointer to next outer when frame is open */
|
||||
};
|
||||
|
||||
}
|
9
rabbit/OuterVar.cpp
Normal file
9
rabbit/OuterVar.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/OuterVar.hpp>
|
||||
|
34
rabbit/OuterVar.hpp
Normal file
34
rabbit/OuterVar.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* @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
|
||||
|
||||
namespace rabbit {
|
||||
enum OuterType {
|
||||
otLOCAL = 0,
|
||||
otOUTER = 1
|
||||
};
|
||||
|
||||
class OuterVar {
|
||||
public:
|
||||
OuterVar(){}
|
||||
OuterVar(const ObjectPtr &name,const ObjectPtr &src, OuterType t) {
|
||||
_name = name;
|
||||
_src=src;
|
||||
_type=t;
|
||||
}
|
||||
OuterVar(const OuterVar &ov) {
|
||||
_type=ov._type;
|
||||
_src=ov._src;
|
||||
_name=ov._name;
|
||||
}
|
||||
rabbit::OuterType _type;
|
||||
rabbit::ObjectPtr _name;
|
||||
rabbit::ObjectPtr _src;
|
||||
};
|
||||
|
||||
}
|
@ -144,13 +144,13 @@ void rabbit::RefTable::allocNodes(uint64_t size)
|
||||
for(n = 0; n < size - 1; n++) {
|
||||
bucks[n] = NULL;
|
||||
temp->refs = 0;
|
||||
new (&temp->obj) rabbit::ObjectPtr;
|
||||
new ((char*)&temp->obj) ObjectPtr;
|
||||
temp->next = temp+1;
|
||||
temp++;
|
||||
}
|
||||
bucks[n] = NULL;
|
||||
temp->refs = 0;
|
||||
new (&temp->obj) rabbit::ObjectPtr;
|
||||
new ((char*)&temp->obj) ObjectPtr;
|
||||
temp->next = NULL;
|
||||
_freelist = nodes;
|
||||
_nodes = nodes;
|
||||
|
@ -5,18 +5,17 @@
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <rabbit/SharedState.hpp>
|
||||
|
||||
|
||||
#include <rabbit/Table.hpp>
|
||||
#include <rabbit/String.hpp>
|
||||
#include <rabbit/RegFunction.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);
|
||||
rabbit::NativeClosure *nc = rabbit::NativeClosure::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))
|
||||
|
@ -8,8 +8,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <etk/Vector.hpp>
|
||||
#include <rabbit/sqconfig.hpp>
|
||||
#include <rabbit/RefTable.hpp>
|
||||
#include <rabbit/rabbit.hpp>
|
||||
|
||||
namespace rabbit {
|
||||
class StringTable;
|
||||
|
@ -376,9 +376,9 @@ bool rabbit::VirtualMachine::init(rabbit::VirtualMachine *friendvm, int64_t stac
|
||||
}
|
||||
|
||||
|
||||
bool rabbit::VirtualMachine::startcall(SQClosure *closure,int64_t target,int64_t args,int64_t stackbase,bool tailcall)
|
||||
bool rabbit::VirtualMachine::startcall(rabbit::Closure *closure,int64_t target,int64_t args,int64_t stackbase,bool tailcall)
|
||||
{
|
||||
SQFunctionProto *func = closure->_function;
|
||||
rabbit::FunctionProto *func = closure->_function;
|
||||
|
||||
int64_t paramssize = func->_nparameters;
|
||||
const int64_t newtop = stackbase + func->_stacksize;
|
||||
@ -434,8 +434,8 @@ bool rabbit::VirtualMachine::startcall(SQClosure *closure,int64_t target,int64_t
|
||||
}
|
||||
|
||||
if (closure->_function->_bgenerator) {
|
||||
SQFunctionProto *f = closure->_function;
|
||||
SQGenerator *gen = SQGenerator::create(_get_shared_state(this), closure);
|
||||
rabbit::FunctionProto *f = closure->_function;
|
||||
rabbit::Generator *gen = rabbit::Generator::create(_get_shared_state(this), closure);
|
||||
if(!gen->yield(this,f->_stacksize))
|
||||
return false;
|
||||
rabbit::ObjectPtr temp;
|
||||
@ -562,8 +562,8 @@ bool rabbit::VirtualMachine::FOREACH_OP(rabbit::ObjectPtr &o1,rabbit::ObjectPtr
|
||||
}
|
||||
break;
|
||||
case rabbit::OT_GENERATOR:
|
||||
if(_generator(o1)->_state == SQGenerator::eDead) _FINISH(exitpos);
|
||||
if(_generator(o1)->_state == SQGenerator::eSuspended) {
|
||||
if(_generator(o1)->_state == rabbit::Generator::eDead) _FINISH(exitpos);
|
||||
if(_generator(o1)->_state == rabbit::Generator::eSuspended) {
|
||||
int64_t idx = 0;
|
||||
if(sq_type(o4) == rabbit::OT_INTEGER) {
|
||||
idx = _integer(o4) + 1;
|
||||
@ -585,13 +585,13 @@ bool rabbit::VirtualMachine::FOREACH_OP(rabbit::ObjectPtr &o1,rabbit::ObjectPtr
|
||||
|
||||
#define _GUARD(exp) { if(!exp) { SQ_THROW();} }
|
||||
|
||||
bool rabbit::VirtualMachine::CLOSURE_OP(rabbit::ObjectPtr &target, SQFunctionProto *func)
|
||||
bool rabbit::VirtualMachine::CLOSURE_OP(rabbit::ObjectPtr &target, rabbit::FunctionProto *func)
|
||||
{
|
||||
int64_t nouters;
|
||||
SQClosure *closure = SQClosure::create(_get_shared_state(this), func,_table(_roottable)->getWeakRef(rabbit::OT_TABLE));
|
||||
rabbit::Closure *closure = rabbit::Closure::create(_get_shared_state(this), func,_table(_roottable)->getWeakRef(rabbit::OT_TABLE));
|
||||
if((nouters = func->_noutervalues)) {
|
||||
for(int64_t i = 0; i<nouters; i++) {
|
||||
SQOuterVar &v = func->_outervalues[i];
|
||||
rabbit::OuterVar &v = func->_outervalues[i];
|
||||
switch(v._type){
|
||||
case otLOCAL:
|
||||
findOuter(closure->_outervalues[i], &STK(_integer(v._src)));
|
||||
@ -671,7 +671,7 @@ bool rabbit::VirtualMachine::IsFalse(rabbit::ObjectPtr &o)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
extern SQInstructionDesc g_InstrDesc[];
|
||||
extern rabbit::InstructionDesc g_InstrDesc[];
|
||||
bool rabbit::VirtualMachine::execute(rabbit::ObjectPtr &closure, int64_t nargs, int64_t stackbase,rabbit::ObjectPtr &outres, rabbit::Bool raiseerror,ExecutionType et)
|
||||
{
|
||||
if ((_nnativecalls + 1) > MAX_NATIVE_CALLS) { raise_error(_SC("Native stack overflow")); return false; }
|
||||
@ -710,7 +710,7 @@ exception_restore:
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
const SQInstruction &_i_ = *ci->_ip++;
|
||||
const rabbit::Instruction &_i_ = *ci->_ip++;
|
||||
//dumpstack(_stackbase);
|
||||
//scprintf("\n[%d] %s %d %d %d %d\n",ci->_ip-_closure(ci->_closure)->_function->_instructions,g_InstrDesc[_i_.op].name,arg0,arg1,arg2,arg3);
|
||||
switch(_i_.op)
|
||||
@ -885,14 +885,14 @@ exception_restore:
|
||||
continue;
|
||||
case _OP_JZ: if(IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue;
|
||||
case _OP_GETOUTER: {
|
||||
SQClosure *cur_cls = _closure(ci->_closure);
|
||||
SQOuter *otr = _outer(cur_cls->_outervalues[arg1]);
|
||||
rabbit::Closure *cur_cls = _closure(ci->_closure);
|
||||
rabbit::Outer *otr = _outer(cur_cls->_outervalues[arg1]);
|
||||
TARGET = *(otr->_valptr);
|
||||
}
|
||||
continue;
|
||||
case _OP_SETOUTER: {
|
||||
SQClosure *cur_cls = _closure(ci->_closure);
|
||||
SQOuter *otr = _outer(cur_cls->_outervalues[arg1]);
|
||||
rabbit::Closure *cur_cls = _closure(ci->_closure);
|
||||
rabbit::Outer *otr = _outer(cur_cls->_outervalues[arg1]);
|
||||
*(otr->_valptr) = STK(arg2);
|
||||
if(arg0 != 0xFF) {
|
||||
TARGET = STK(arg2);
|
||||
@ -994,8 +994,8 @@ exception_restore:
|
||||
raise_error(_SC("attempt to perform a bitwise op on a %s"), getTypeName(STK(arg1)));
|
||||
SQ_THROW();
|
||||
case _OP_CLOSURE: {
|
||||
SQClosure *c = ci->_closure._unVal.pClosure;
|
||||
SQFunctionProto *fp = c->_function;
|
||||
rabbit::Closure *c = ci->_closure._unVal.pClosure;
|
||||
rabbit::FunctionProto *fp = c->_function;
|
||||
if(!CLOSURE_OP(TARGET,fp->_functions[arg1]._unVal.pFunctionProto)) { SQ_THROW(); }
|
||||
continue;
|
||||
}
|
||||
@ -1026,13 +1026,13 @@ exception_restore:
|
||||
continue;
|
||||
case _OP_POSTFOREACH:
|
||||
assert(sq_type(STK(arg0)) == rabbit::OT_GENERATOR);
|
||||
if(_generator(STK(arg0))->_state == SQGenerator::eDead)
|
||||
if(_generator(STK(arg0))->_state == rabbit::Generator::eDead)
|
||||
ci->_ip += (sarg1 - 1);
|
||||
continue;
|
||||
case _OP_CLONE: _GUARD(clone(STK(arg1), TARGET)); continue;
|
||||
case _OP_TYPEOF: _GUARD(typeOf(STK(arg1), TARGET)) continue;
|
||||
case _OP_PUSHTRAP:{
|
||||
SQInstruction *_iv = _closure(ci->_closure)->_function->_instructions;
|
||||
rabbit::Instruction *_iv = _closure(ci->_closure)->_function->_instructions;
|
||||
_etraps.pushBack(rabbit::ExceptionTrap(_top,_stackbase, &_iv[(ci->_ip-_iv)+arg1], arg0)); traps++;
|
||||
ci->_etraps++;
|
||||
}
|
||||
@ -1049,7 +1049,7 @@ exception_restore:
|
||||
_GUARD(newSlotA(STK(arg1),STK(arg2),STK(arg3),(arg0&NEW_SLOT_ATTRIBUTES_FLAG) ? STK(arg2-1) : rabbit::ObjectPtr(),(arg0&NEW_SLOT_STATIC_FLAG)?true:false,false));
|
||||
continue;
|
||||
case _OP_GETBASE:{
|
||||
SQClosure *clo = _closure(ci->_closure);
|
||||
rabbit::Closure *clo = _closure(ci->_closure);
|
||||
if(clo->_base) {
|
||||
TARGET = clo->_base;
|
||||
}
|
||||
@ -1127,7 +1127,7 @@ void rabbit::VirtualMachine::callerrorHandler(rabbit::ObjectPtr &error)
|
||||
void rabbit::VirtualMachine::callDebugHook(int64_t type,int64_t forcedline)
|
||||
{
|
||||
_debughook = false;
|
||||
SQFunctionProto *func=_closure(ci->_closure)->_function;
|
||||
rabbit::FunctionProto *func=_closure(ci->_closure)->_function;
|
||||
if(_debughook_native) {
|
||||
const rabbit::Char *src = sq_type(func->_sourcename) == rabbit::OT_STRING?_stringval(func->_sourcename):NULL;
|
||||
const rabbit::Char *fname = sq_type(func->_name) == rabbit::OT_STRING?_stringval(func->_name):NULL;
|
||||
@ -1148,7 +1148,7 @@ void rabbit::VirtualMachine::callDebugHook(int64_t type,int64_t forcedline)
|
||||
_debughook = true;
|
||||
}
|
||||
|
||||
bool rabbit::VirtualMachine::callNative(SQNativeClosure *nclosure, int64_t nargs, int64_t newbase, rabbit::ObjectPtr &retval, int32_t target,bool &suspend, bool &tailcall)
|
||||
bool rabbit::VirtualMachine::callNative(rabbit::NativeClosure *nclosure, int64_t nargs, int64_t newbase, rabbit::ObjectPtr &retval, int32_t target,bool &suspend, bool &tailcall)
|
||||
{
|
||||
int64_t nparamscheck = nclosure->_nparamscheck;
|
||||
int64_t newtop = newbase + nargs + nclosure->_noutervalues;
|
||||
@ -1217,7 +1217,7 @@ bool rabbit::VirtualMachine::callNative(SQNativeClosure *nclosure, int64_t nargs
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rabbit::VirtualMachine::tailcall(SQClosure *closure, int64_t parambase,int64_t nparams)
|
||||
bool rabbit::VirtualMachine::tailcall(rabbit::Closure *closure, int64_t parambase,int64_t nparams)
|
||||
{
|
||||
int64_t last_top = _top;
|
||||
rabbit::ObjectPtr clo = closure;
|
||||
@ -1629,9 +1629,9 @@ bool rabbit::VirtualMachine::callMetaMethod(rabbit::ObjectPtr &closure,rabbit::M
|
||||
|
||||
void rabbit::VirtualMachine::findOuter(rabbit::ObjectPtr &target, rabbit::ObjectPtr *stackindex)
|
||||
{
|
||||
SQOuter **pp = &_openouters;
|
||||
SQOuter *p;
|
||||
SQOuter *otr;
|
||||
rabbit::Outer **pp = &_openouters;
|
||||
rabbit::Outer *p;
|
||||
rabbit::Outer *otr;
|
||||
|
||||
while ((p = *pp) != NULL && p->_valptr >= stackindex) {
|
||||
if (p->_valptr == stackindex) {
|
||||
@ -1640,7 +1640,7 @@ void rabbit::VirtualMachine::findOuter(rabbit::ObjectPtr &target, rabbit::Object
|
||||
}
|
||||
pp = &p->_next;
|
||||
}
|
||||
otr = SQOuter::create(_get_shared_state(this), stackindex);
|
||||
otr = rabbit::Outer::create(_get_shared_state(this), stackindex);
|
||||
otr->_next = *pp;
|
||||
// TODO: rework this, this is absolutly not safe...
|
||||
otr->_idx = (stackindex - &_stack[0]);
|
||||
@ -1699,7 +1699,7 @@ void rabbit::VirtualMachine::leaveFrame() {
|
||||
|
||||
void rabbit::VirtualMachine::relocateOuters()
|
||||
{
|
||||
SQOuter *p = _openouters;
|
||||
rabbit::Outer *p = _openouters;
|
||||
while (p) {
|
||||
p->_valptr = &_stack[p->_idx];
|
||||
p = p->_next;
|
||||
@ -1707,7 +1707,7 @@ void rabbit::VirtualMachine::relocateOuters()
|
||||
}
|
||||
|
||||
void rabbit::VirtualMachine::closeOuters(rabbit::ObjectPtr *stackindex) {
|
||||
SQOuter *p;
|
||||
rabbit::Outer *p;
|
||||
while ((p = _openouters) != NULL && p->_valptr >= stackindex) {
|
||||
p->_value = *(p->_valptr);
|
||||
p->_valptr = &p->_value;
|
||||
|
@ -38,10 +38,10 @@ namespace rabbit {
|
||||
{
|
||||
public:
|
||||
struct callInfo{
|
||||
SQInstruction *_ip;
|
||||
rabbit::Instruction *_ip;
|
||||
rabbit::ObjectPtr *_literals;
|
||||
rabbit::ObjectPtr _closure;
|
||||
SQGenerator *_generator;
|
||||
rabbit::Generator *_generator;
|
||||
int32_t _etraps;
|
||||
int32_t _prevstkbase;
|
||||
int32_t _prevtop;
|
||||
@ -64,10 +64,10 @@ namespace rabbit {
|
||||
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);
|
||||
//starts a native call return when the NATIVE closure returns
|
||||
bool callNative(SQNativeClosure *nclosure, int64_t nargs, int64_t newbase, rabbit::ObjectPtr &retval, int32_t target, bool &suspend,bool &tailcall);
|
||||
bool tailcall(SQClosure *closure, int64_t firstparam, int64_t nparams);
|
||||
bool callNative(rabbit::NativeClosure *nclosure, int64_t nargs, int64_t newbase, rabbit::ObjectPtr &retval, int32_t target, bool &suspend,bool &tailcall);
|
||||
bool tailcall(rabbit::Closure *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 startcall(rabbit::Closure *closure, int64_t target, int64_t nargs, int64_t stackbase, bool tailcall);
|
||||
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);
|
||||
@ -110,7 +110,7 @@ namespace rabbit {
|
||||
bool BW_OP(uint64_t op,rabbit::ObjectPtr &trg,const rabbit::ObjectPtr &o1,const rabbit::ObjectPtr &o2);
|
||||
bool NEG_OP(rabbit::ObjectPtr &trg,const rabbit::ObjectPtr &o1);
|
||||
bool CMP_OP(CmpOP op, const rabbit::ObjectPtr &o1,const rabbit::ObjectPtr &o2,rabbit::ObjectPtr &res);
|
||||
bool CLOSURE_OP(rabbit::ObjectPtr &target, SQFunctionProto *func);
|
||||
bool CLOSURE_OP(rabbit::ObjectPtr &target, rabbit::FunctionProto *func);
|
||||
bool CLASS_OP(rabbit::ObjectPtr &target,int64_t base,int64_t attrs);
|
||||
//return true if the loop is finished
|
||||
bool FOREACH_OP(rabbit::ObjectPtr &o1,rabbit::ObjectPtr &o2,rabbit::ObjectPtr &o3,rabbit::ObjectPtr &o4,int64_t arg_2,int exitpos,int &jump);
|
||||
@ -152,7 +152,7 @@ namespace rabbit {
|
||||
|
||||
int64_t _top;
|
||||
int64_t _stackbase;
|
||||
SQOuter* _openouters;
|
||||
rabbit::Outer* _openouters;
|
||||
rabbit::ObjectPtr _roottable;
|
||||
rabbit::ObjectPtr _lasterror;
|
||||
rabbit::ObjectPtr _errorhandler;
|
||||
|
@ -138,7 +138,7 @@ rabbit::Result sq_compile(rabbit::VirtualMachine* v,SQLEXREADFUNC read,rabbit::U
|
||||
rabbit::ObjectPtr o;
|
||||
#ifndef NO_COMPILER
|
||||
if(compile(v, read, p, sourcename, o, raiseerror?true:false, _get_shared_state(v)->_debuginfo)) {
|
||||
v->push(SQClosure::create(_get_shared_state(v), _funcproto(o), _table(v->_roottable)->getWeakRef(rabbit::OT_TABLE)));
|
||||
v->push(rabbit::Closure::create(_get_shared_state(v), _funcproto(o), _table(v->_roottable)->getWeakRef(rabbit::OT_TABLE)));
|
||||
return SQ_OK;
|
||||
}
|
||||
return SQ_ERROR;
|
||||
@ -386,7 +386,7 @@ rabbit::Result sq_arrayinsert(rabbit::VirtualMachine* v,int64_t idx,int64_t dest
|
||||
|
||||
void sq_newclosure(rabbit::VirtualMachine* v,SQFUNCTION func,uint64_t nfreevars)
|
||||
{
|
||||
SQNativeClosure *nc = SQNativeClosure::create(_get_shared_state(v), func,nfreevars);
|
||||
rabbit::NativeClosure *nc = rabbit::NativeClosure::create(_get_shared_state(v), func,nfreevars);
|
||||
nc->_nparamscheck = 0;
|
||||
for(uint64_t i = 0; i < nfreevars; i++) {
|
||||
nc->_outervalues[i] = v->top();
|
||||
@ -399,15 +399,15 @@ rabbit::Result sq_getclosureinfo(rabbit::VirtualMachine* v,int64_t idx,uint64_t
|
||||
{
|
||||
rabbit::Object o = stack_get(v, idx);
|
||||
if(sq_type(o) == rabbit::OT_CLOSURE) {
|
||||
SQClosure *c = _closure(o);
|
||||
SQFunctionProto *proto = c->_function;
|
||||
rabbit::Closure *c = _closure(o);
|
||||
rabbit::FunctionProto *proto = c->_function;
|
||||
*nparams = (uint64_t)proto->_nparameters;
|
||||
*nfreevars = (uint64_t)proto->_noutervalues;
|
||||
return SQ_OK;
|
||||
}
|
||||
else if(sq_type(o) == rabbit::OT_NATIVECLOSURE)
|
||||
{
|
||||
SQNativeClosure *c = _nativeclosure(o);
|
||||
rabbit::NativeClosure *c = _nativeclosure(o);
|
||||
*nparams = (uint64_t)c->_nparamscheck;
|
||||
*nfreevars = c->_noutervalues;
|
||||
return SQ_OK;
|
||||
@ -419,7 +419,7 @@ rabbit::Result sq_setnativeclosurename(rabbit::VirtualMachine* v,int64_t idx,con
|
||||
{
|
||||
rabbit::Object o = stack_get(v, idx);
|
||||
if(sq_isnativeclosure(o)) {
|
||||
SQNativeClosure *nc = _nativeclosure(o);
|
||||
rabbit::NativeClosure *nc = _nativeclosure(o);
|
||||
nc->_name = rabbit::String::create(_get_shared_state(v),name);
|
||||
return SQ_OK;
|
||||
}
|
||||
@ -431,7 +431,7 @@ rabbit::Result sq_setparamscheck(rabbit::VirtualMachine* v,int64_t nparamscheck,
|
||||
rabbit::Object o = stack_get(v, -1);
|
||||
if(!sq_isnativeclosure(o))
|
||||
return sq_throwerror(v, _SC("native closure expected"));
|
||||
SQNativeClosure *nc = _nativeclosure(o);
|
||||
rabbit::NativeClosure *nc = _nativeclosure(o);
|
||||
nc->_nparamscheck = nparamscheck;
|
||||
if(typemask) {
|
||||
etk::Vector<int64_t> res;
|
||||
@ -463,7 +463,7 @@ rabbit::Result sq_bindenv(rabbit::VirtualMachine* v,int64_t idx)
|
||||
rabbit::WeakRef *w = _refcounted(env)->getWeakRef(sq_type(env));
|
||||
rabbit::ObjectPtr ret;
|
||||
if(sq_isclosure(o)) {
|
||||
SQClosure *c = _closure(o)->clone();
|
||||
rabbit::Closure *c = _closure(o)->clone();
|
||||
__Objrelease(c->_env);
|
||||
c->_env = w;
|
||||
__ObjaddRef(c->_env);
|
||||
@ -474,7 +474,7 @@ rabbit::Result sq_bindenv(rabbit::VirtualMachine* v,int64_t idx)
|
||||
ret = c;
|
||||
}
|
||||
else { //then must be a native closure
|
||||
SQNativeClosure *c = _nativeclosure(o)->clone();
|
||||
rabbit::NativeClosure *c = _nativeclosure(o)->clone();
|
||||
__Objrelease(c->_env);
|
||||
c->_env = w;
|
||||
__ObjaddRef(c->_env);
|
||||
@ -1109,8 +1109,8 @@ const rabbit::Char *sq_getlocal(rabbit::VirtualMachine* v,uint64_t level,uint64_
|
||||
rabbit::VirtualMachine::callInfo &ci=v->_callsstack[lvl];
|
||||
if(sq_type(ci._closure)!=rabbit::OT_CLOSURE)
|
||||
return NULL;
|
||||
SQClosure *c=_closure(ci._closure);
|
||||
SQFunctionProto *func=c->_function;
|
||||
rabbit::Closure *c=_closure(ci._closure);
|
||||
rabbit::FunctionProto *func=c->_function;
|
||||
if(func->_noutervalues > (int64_t)idx) {
|
||||
v->push(*_outer(c->_outervalues[idx])->_valptr);
|
||||
return _stringval(func->_outervalues[idx]._name);
|
||||
@ -1208,7 +1208,7 @@ rabbit::Result sq_tailcall(rabbit::VirtualMachine* v, int64_t nparams)
|
||||
if (sq_type(res) != rabbit::OT_CLOSURE) {
|
||||
return sq_throwerror(v, _SC("only closure can be tail called"));
|
||||
}
|
||||
SQClosure *clo = _closure(res);
|
||||
rabbit::Closure *clo = _closure(res);
|
||||
if (clo->_function->_bgenerator)
|
||||
{
|
||||
return sq_throwerror(v, _SC("generators cannot be tail called"));
|
||||
@ -1312,7 +1312,7 @@ rabbit::Result sq_readclosure(rabbit::VirtualMachine* v,SQREADFUNC r,rabbit::Use
|
||||
return sq_throwerror(v,_SC("io error"));
|
||||
if(tag != SQ_BYTECODE_STREAM_TAG)
|
||||
return sq_throwerror(v,_SC("invalid stream"));
|
||||
if(!SQClosure::load(v,up,r,closure))
|
||||
if(!rabbit::Closure::load(v,up,r,closure))
|
||||
return SQ_ERROR;
|
||||
v->push(closure);
|
||||
return SQ_OK;
|
||||
@ -1351,17 +1351,17 @@ const rabbit::Char *sq_getfreevariable(rabbit::VirtualMachine* v,int64_t idx,uin
|
||||
switch(sq_type(self))
|
||||
{
|
||||
case rabbit::OT_CLOSURE:{
|
||||
SQClosure *clo = _closure(self);
|
||||
SQFunctionProto *fp = clo->_function;
|
||||
rabbit::Closure *clo = _closure(self);
|
||||
rabbit::FunctionProto *fp = clo->_function;
|
||||
if(((uint64_t)fp->_noutervalues) > nval) {
|
||||
v->push(*(_outer(clo->_outervalues[nval])->_valptr));
|
||||
SQOuterVar &ov = fp->_outervalues[nval];
|
||||
rabbit::OuterVar &ov = fp->_outervalues[nval];
|
||||
name = _stringval(ov._name);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case rabbit::OT_NATIVECLOSURE:{
|
||||
SQNativeClosure *clo = _nativeclosure(self);
|
||||
rabbit::NativeClosure *clo = _nativeclosure(self);
|
||||
if(clo->_noutervalues > nval) {
|
||||
v->push(clo->_outervalues[nval]);
|
||||
name = _SC("@NATIVE");
|
||||
@ -1379,7 +1379,7 @@ rabbit::Result sq_setfreevariable(rabbit::VirtualMachine* v,int64_t idx,uint64_t
|
||||
switch(sq_type(self))
|
||||
{
|
||||
case rabbit::OT_CLOSURE:{
|
||||
SQFunctionProto *fp = _closure(self)->_function;
|
||||
rabbit::FunctionProto *fp = _closure(self)->_function;
|
||||
if(((uint64_t)fp->_noutervalues) > nval){
|
||||
*(_outer(_closure(self)->_outervalues[nval])->_valptr) = stack_get(v,-1);
|
||||
}
|
||||
|
@ -972,7 +972,7 @@ static int64_t closure_getinfos(rabbit::VirtualMachine* v) {
|
||||
rabbit::Object o = stack_get(v,1);
|
||||
rabbit::Table *res = rabbit::Table::create(_get_shared_state(v),4);
|
||||
if(sq_type(o) == rabbit::OT_CLOSURE) {
|
||||
SQFunctionProto *f = _closure(o)->_function;
|
||||
rabbit::FunctionProto *f = _closure(o)->_function;
|
||||
int64_t nparams = f->_nparameters + (f->_varparams?1:0);
|
||||
rabbit::ObjectPtr params = rabbit::Array::create(_get_shared_state(v),nparams);
|
||||
rabbit::ObjectPtr defparams = rabbit::Array::create(_get_shared_state(v),f->_ndefaultparams);
|
||||
@ -993,7 +993,7 @@ static int64_t closure_getinfos(rabbit::VirtualMachine* v) {
|
||||
res->newSlot(rabbit::String::create(_get_shared_state(v),_SC("defparams"),-1),defparams);
|
||||
}
|
||||
else { //rabbit::OT_NATIVECLOSURE
|
||||
SQNativeClosure *nc = _nativeclosure(o);
|
||||
rabbit::NativeClosure *nc = _nativeclosure(o);
|
||||
res->newSlot(rabbit::String::create(_get_shared_state(v),_SC("native"),-1),true);
|
||||
res->newSlot(rabbit::String::create(_get_shared_state(v),_SC("name"),-1),nc->_name);
|
||||
res->newSlot(rabbit::String::create(_get_shared_state(v),_SC("paramscheck"),-1),nc->_nparamscheck);
|
||||
@ -1032,9 +1032,9 @@ static int64_t generator_getstatus(rabbit::VirtualMachine* v)
|
||||
{
|
||||
rabbit::Object &o=stack_get(v,1);
|
||||
switch(_generator(o)->_state){
|
||||
case SQGenerator::eSuspended:v->push(rabbit::String::create(_get_shared_state(v),_SC("suspended")));break;
|
||||
case SQGenerator::eRunning:v->push(rabbit::String::create(_get_shared_state(v),_SC("running")));break;
|
||||
case SQGenerator::eDead:v->push(rabbit::String::create(_get_shared_state(v),_SC("dead")));break;
|
||||
case rabbit::Generator::eSuspended:v->push(rabbit::String::create(_get_shared_state(v),_SC("suspended")));break;
|
||||
case rabbit::Generator::eRunning:v->push(rabbit::String::create(_get_shared_state(v),_SC("running")));break;
|
||||
case rabbit::Generator::eDead:v->push(rabbit::String::create(_get_shared_state(v),_SC("dead")));break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,196 +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/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 SQClosure : public rabbit::RefCounted
|
||||
{
|
||||
private:
|
||||
SQClosure(rabbit::SharedState *ss,SQFunctionProto *func){
|
||||
_function = func;
|
||||
__ObjaddRef(_function); _base = NULL;
|
||||
_env = NULL;
|
||||
_root=NULL;
|
||||
}
|
||||
public:
|
||||
static SQClosure *create(rabbit::SharedState *ss,SQFunctionProto *func,rabbit::WeakRef *root){
|
||||
int64_t size = _CALC_CLOSURE_SIZE(func);
|
||||
SQClosure *nc=(SQClosure*)SQ_MALLOC(size);
|
||||
new (nc) SQClosure(ss,func);
|
||||
nc->_outervalues = (rabbit::ObjectPtr *)(nc + 1);
|
||||
nc->_defaultparams = &nc->_outervalues[func->_noutervalues];
|
||||
nc->_root = root;
|
||||
__ObjaddRef(nc->_root);
|
||||
_CONSTRUCT_VECTOR(rabbit::ObjectPtr,func->_noutervalues,nc->_outervalues);
|
||||
_CONSTRUCT_VECTOR(rabbit::ObjectPtr,func->_ndefaultparams,nc->_defaultparams);
|
||||
return nc;
|
||||
}
|
||||
void release(){
|
||||
SQFunctionProto *f = _function;
|
||||
int64_t size = _CALC_CLOSURE_SIZE(f);
|
||||
_DESTRUCT_VECTOR(ObjectPtr,f->_noutervalues,_outervalues);
|
||||
_DESTRUCT_VECTOR(ObjectPtr,f->_ndefaultparams,_defaultparams);
|
||||
__Objrelease(_function);
|
||||
this->~SQClosure();
|
||||
sq_vm_free(this,size);
|
||||
}
|
||||
void setRoot(rabbit::WeakRef *r)
|
||||
{
|
||||
__Objrelease(_root);
|
||||
_root = r;
|
||||
__ObjaddRef(_root);
|
||||
}
|
||||
SQClosure *clone()
|
||||
{
|
||||
SQFunctionProto *f = _function;
|
||||
SQClosure * ret = SQClosure::create(NULL,f,_root);
|
||||
ret->_env = _env;
|
||||
if(ret->_env) __ObjaddRef(ret->_env);
|
||||
_COPY_VECTOR(ret->_outervalues,_outervalues,f->_noutervalues);
|
||||
_COPY_VECTOR(ret->_defaultparams,_defaultparams,f->_ndefaultparams);
|
||||
return ret;
|
||||
}
|
||||
~SQClosure();
|
||||
|
||||
bool save(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQWRITEFUNC write);
|
||||
static bool load(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQREADFUNC read,rabbit::ObjectPtr &ret);
|
||||
rabbit::WeakRef *_env;
|
||||
rabbit::WeakRef *_root;
|
||||
rabbit::Class *_base;
|
||||
SQFunctionProto *_function;
|
||||
rabbit::ObjectPtr *_outervalues;
|
||||
rabbit::ObjectPtr *_defaultparams;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////
|
||||
struct SQOuter : public rabbit::RefCounted
|
||||
{
|
||||
|
||||
private:
|
||||
SQOuter(rabbit::SharedState *ss, rabbit::ObjectPtr *outer){
|
||||
_valptr = outer;
|
||||
_next = NULL;
|
||||
}
|
||||
|
||||
public:
|
||||
static SQOuter *create(rabbit::SharedState *ss, rabbit::ObjectPtr *outer)
|
||||
{
|
||||
SQOuter *nc = (SQOuter*)SQ_MALLOC(sizeof(SQOuter));
|
||||
new (nc) SQOuter(ss, outer);
|
||||
return nc;
|
||||
}
|
||||
~SQOuter() {
|
||||
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
this->~SQOuter();
|
||||
sq_vm_free(this,sizeof(SQOuter));
|
||||
}
|
||||
|
||||
rabbit::ObjectPtr *_valptr; /* pointer to value on stack, or _value below */
|
||||
int64_t _idx; /* idx in stack array, for relocation */
|
||||
rabbit::ObjectPtr _value; /* value of outer after stack frame is closed */
|
||||
SQOuter *_next; /* pointer to next outer when frame is open */
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////
|
||||
struct SQGenerator : public rabbit::RefCounted
|
||||
{
|
||||
enum SQGeneratorState{eRunning,eSuspended,eDead};
|
||||
private:
|
||||
SQGenerator(rabbit::SharedState *ss,SQClosure *closure){
|
||||
_closure=closure;
|
||||
_state=eRunning;
|
||||
_ci._generator=NULL;
|
||||
}
|
||||
public:
|
||||
static SQGenerator *create(rabbit::SharedState *ss,SQClosure *closure){
|
||||
SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));
|
||||
new (nc) SQGenerator(ss,closure);
|
||||
return nc;
|
||||
}
|
||||
~SQGenerator()
|
||||
{
|
||||
|
||||
}
|
||||
void kill(){
|
||||
_state=eDead;
|
||||
_stack.resize(0);
|
||||
_closure.Null();}
|
||||
void release(){
|
||||
sq_delete(this,SQGenerator);
|
||||
}
|
||||
|
||||
bool yield(rabbit::VirtualMachine *v,int64_t target);
|
||||
bool resume(rabbit::VirtualMachine *v,rabbit::ObjectPtr &dest);
|
||||
rabbit::ObjectPtr _closure;
|
||||
etk::Vector<rabbit::ObjectPtr> _stack;
|
||||
rabbit::VirtualMachine::callInfo _ci;
|
||||
etk::Vector<rabbit::ExceptionTrap> _etraps;
|
||||
SQGeneratorState _state;
|
||||
};
|
||||
|
||||
#define _CALC_NATVIVECLOSURE_SIZE(noutervalues) (sizeof(SQNativeClosure) + (noutervalues*sizeof(rabbit::ObjectPtr)))
|
||||
|
||||
struct SQNativeClosure : public rabbit::RefCounted
|
||||
{
|
||||
private:
|
||||
SQNativeClosure(rabbit::SharedState *ss,SQFUNCTION func){
|
||||
_function=func;
|
||||
_env = NULL;
|
||||
}
|
||||
public:
|
||||
static SQNativeClosure *create(rabbit::SharedState *ss,SQFUNCTION func,int64_t nouters)
|
||||
{
|
||||
int64_t size = _CALC_NATVIVECLOSURE_SIZE(nouters);
|
||||
SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(size);
|
||||
new (nc) SQNativeClosure(ss,func);
|
||||
nc->_outervalues = (rabbit::ObjectPtr *)(nc + 1);
|
||||
nc->_noutervalues = nouters;
|
||||
_CONSTRUCT_VECTOR(rabbit::ObjectPtr,nc->_noutervalues,nc->_outervalues);
|
||||
return nc;
|
||||
}
|
||||
SQNativeClosure *clone()
|
||||
{
|
||||
SQNativeClosure * ret = SQNativeClosure::create(NULL,_function,_noutervalues);
|
||||
ret->_env = _env;
|
||||
if(ret->_env) __ObjaddRef(ret->_env);
|
||||
ret->_name = _name;
|
||||
_COPY_VECTOR(ret->_outervalues,_outervalues,_noutervalues);
|
||||
ret->_typecheck = _typecheck;
|
||||
ret->_nparamscheck = _nparamscheck;
|
||||
return ret;
|
||||
}
|
||||
~SQNativeClosure()
|
||||
{
|
||||
__Objrelease(_env);
|
||||
}
|
||||
void release(){
|
||||
int64_t size = _CALC_NATVIVECLOSURE_SIZE(_noutervalues);
|
||||
_DESTRUCT_VECTOR(ObjectPtr,_noutervalues,_outervalues);
|
||||
this->~SQNativeClosure();
|
||||
sq_free(this,size);
|
||||
}
|
||||
|
||||
int64_t _nparamscheck;
|
||||
etk::Vector<int64_t> _typecheck;
|
||||
rabbit::ObjectPtr *_outervalues;
|
||||
uint64_t _noutervalues;
|
||||
rabbit::WeakRef *_env;
|
||||
SQFUNCTION _function;
|
||||
rabbit::ObjectPtr _name;
|
||||
};
|
||||
|
||||
|
@ -1,84 +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
|
||||
namespace rabbit {
|
||||
class VirtualMachine;
|
||||
}
|
||||
|
||||
#define TK_IDENTIFIER 258
|
||||
#define TK_STRING_LITERAL 259
|
||||
#define TK_INTEGER 260
|
||||
#define TK_FLOAT 261
|
||||
#define TK_BASE 262
|
||||
#define TK_DELETE 263
|
||||
#define TK_EQ 264
|
||||
#define TK_NE 265
|
||||
#define TK_LE 266
|
||||
#define TK_GE 267
|
||||
#define TK_SWITCH 268
|
||||
#define TK_ARROW 269
|
||||
#define TK_AND 270
|
||||
#define TK_OR 271
|
||||
#define TK_IF 272
|
||||
#define TK_ELSE 273
|
||||
#define TK_WHILE 274
|
||||
#define TK_BREAK 275
|
||||
#define TK_FOR 276
|
||||
#define TK_DO 277
|
||||
#define TK_NULL 278
|
||||
#define TK_FOREACH 279
|
||||
#define TK_IN 280
|
||||
#define TK_NEWSLOT 281
|
||||
#define TK_MODULO 282
|
||||
#define TK_LOCAL 283
|
||||
#define TK_CLONE 284
|
||||
#define TK_FUNCTION 285
|
||||
#define TK_RETURN 286
|
||||
#define TK_TYPEOF 287
|
||||
#define TK_UMINUS 288
|
||||
#define TK_PLUSEQ 289
|
||||
#define TK_MINUSEQ 290
|
||||
#define TK_CONTINUE 291
|
||||
#define TK_YIELD 292
|
||||
#define TK_TRY 293
|
||||
#define TK_CATCH 294
|
||||
#define TK_THROW 295
|
||||
#define TK_SHIFTL 296
|
||||
#define TK_SHIFTR 297
|
||||
#define TK_RESUME 298
|
||||
#define TK_DOUBLE_COLON 299
|
||||
#define TK_CASE 300
|
||||
#define TK_DEFAULT 301
|
||||
#define TK_THIS 302
|
||||
#define TK_PLUSPLUS 303
|
||||
#define TK_MINUSMINUS 304
|
||||
#define TK_3WAYSCMP 305
|
||||
#define TK_USHIFTR 306
|
||||
#define TK_CLASS 307
|
||||
#define TK_EXTENDS 308
|
||||
#define TK_CONSTRUCTOR 310
|
||||
#define TK_INSTANCEOF 311
|
||||
#define TK_VARPARAMS 312
|
||||
#define TK___LINE__ 313
|
||||
#define TK___FILE__ 314
|
||||
#define TK_TRUE 315
|
||||
#define TK_FALSE 316
|
||||
#define TK_MULEQ 317
|
||||
#define TK_DIVEQ 318
|
||||
#define TK_MODEQ 319
|
||||
#define TK_ATTR_OPEN 320
|
||||
#define TK_ATTR_CLOSE 321
|
||||
#define TK_STATIC 322
|
||||
#define TK_ENUM 323
|
||||
#define TK_CONST 324
|
||||
#define TK_RAWCALL 325
|
||||
|
||||
|
||||
|
||||
typedef void(*compilererrorFunc)(void *ud, const rabbit::Char *s);
|
||||
bool compile(rabbit::VirtualMachine *vm, SQLEXREADFUNC rg, rabbit::UserPointer up, const rabbit::Char *sourcename, rabbit::ObjectPtr &out, bool raiseerror, bool lineinfo);
|
@ -124,11 +124,21 @@ namespace rabbit {
|
||||
#define SQTrue (1)
|
||||
#define SQFalse (0)
|
||||
|
||||
struct SQClosure;
|
||||
struct SQGenerator;
|
||||
struct SQNativeClosure;
|
||||
struct SQFunctionProto;
|
||||
struct SQOuter;
|
||||
|
||||
#ifdef _SQ64
|
||||
#define UINT_MINUS_ONE (0xFFFFFFFFFFFFFFFF)
|
||||
#else
|
||||
#define UINT_MINUS_ONE (0xFFFFFFFF)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
struct rabbit::Closure;
|
||||
struct rabbit::Generator;
|
||||
struct rabbit::NativeClosure;
|
||||
struct rabbit::FunctionProto;
|
||||
struct rabbit::Outer;
|
||||
namespace rabbit {
|
||||
class UserData;
|
||||
class Array;
|
||||
|
@ -21,8 +21,8 @@ rabbit::Result sq_getfunctioninfo(rabbit::VirtualMachine* v,int64_t level,rabbit
|
||||
if (cssize > level) {
|
||||
rabbit::VirtualMachine::callInfo &ci = v->_callsstack[cssize-level-1];
|
||||
if(sq_isclosure(ci._closure)) {
|
||||
SQClosure *c = _closure(ci._closure);
|
||||
SQFunctionProto *proto = c->_function;
|
||||
rabbit::Closure *c = _closure(ci._closure);
|
||||
rabbit::FunctionProto *proto = c->_function;
|
||||
fi->funcid = proto;
|
||||
fi->name = sq_type(proto->_name) == rabbit::OT_STRING?_stringval(proto->_name):_SC("unknown");
|
||||
fi->source = sq_type(proto->_sourcename) == rabbit::OT_STRING?_stringval(proto->_sourcename):_SC("unknown");
|
||||
@ -41,7 +41,7 @@ rabbit::Result sq_stackinfos(rabbit::VirtualMachine* v, int64_t level, rabbit::S
|
||||
rabbit::VirtualMachine::callInfo &ci = v->_callsstack[cssize-level-1];
|
||||
switch (sq_type(ci._closure)) {
|
||||
case rabbit::OT_CLOSURE:{
|
||||
SQFunctionProto *func = _closure(ci._closure)->_function;
|
||||
rabbit::FunctionProto *func = _closure(ci._closure)->_function;
|
||||
if (sq_type(func->_name) == rabbit::OT_STRING)
|
||||
si->funcname = _stringval(func->_name);
|
||||
if (sq_type(func->_sourcename) == rabbit::OT_STRING)
|
||||
|
@ -1,152 +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/sqopcodes.hpp>
|
||||
|
||||
enum SQOuterType {
|
||||
otLOCAL = 0,
|
||||
otOUTER = 1
|
||||
};
|
||||
|
||||
struct SQOuterVar
|
||||
{
|
||||
|
||||
SQOuterVar(){}
|
||||
SQOuterVar(const rabbit::ObjectPtr &name,const rabbit::ObjectPtr &src,SQOuterType t)
|
||||
{
|
||||
_name = name;
|
||||
_src=src;
|
||||
_type=t;
|
||||
}
|
||||
SQOuterVar(const SQOuterVar &ov)
|
||||
{
|
||||
_type=ov._type;
|
||||
_src=ov._src;
|
||||
_name=ov._name;
|
||||
}
|
||||
SQOuterType _type;
|
||||
rabbit::ObjectPtr _name;
|
||||
rabbit::ObjectPtr _src;
|
||||
};
|
||||
|
||||
struct SQLocalVarInfo
|
||||
{
|
||||
SQLocalVarInfo():_start_op(0),_end_op(0),_pos(0){}
|
||||
SQLocalVarInfo(const SQLocalVarInfo &lvi)
|
||||
{
|
||||
_name=lvi._name;
|
||||
_start_op=lvi._start_op;
|
||||
_end_op=lvi._end_op;
|
||||
_pos=lvi._pos;
|
||||
}
|
||||
rabbit::ObjectPtr _name;
|
||||
uint64_t _start_op;
|
||||
uint64_t _end_op;
|
||||
uint64_t _pos;
|
||||
};
|
||||
|
||||
struct SQLineInfo { int64_t _line;int64_t _op; };
|
||||
|
||||
typedef etk::Vector<SQOuterVar> SQOuterVarVec;
|
||||
typedef etk::Vector<SQLocalVarInfo> SQLocalVarInfoVec;
|
||||
typedef etk::Vector<SQLineInfo> SQLineInfoVec;
|
||||
|
||||
#define _FUNC_SIZE(ni,nl,nparams,nfuncs,nouters,nlineinf,localinf,defparams) (sizeof(SQFunctionProto) \
|
||||
+((ni-1)*sizeof(SQInstruction))+(nl*sizeof(rabbit::ObjectPtr)) \
|
||||
+(nparams*sizeof(rabbit::ObjectPtr))+(nfuncs*sizeof(rabbit::ObjectPtr)) \
|
||||
+(nouters*sizeof(SQOuterVar))+(nlineinf*sizeof(SQLineInfo)) \
|
||||
+(localinf*sizeof(SQLocalVarInfo))+(defparams*sizeof(int64_t)))
|
||||
|
||||
|
||||
struct SQFunctionProto : public rabbit::RefCounted
|
||||
{
|
||||
private:
|
||||
SQFunctionProto(rabbit::SharedState *ss);
|
||||
~SQFunctionProto();
|
||||
|
||||
public:
|
||||
static SQFunctionProto *create(rabbit::SharedState *ss,int64_t ninstructions,
|
||||
int64_t nliterals,int64_t nparameters,
|
||||
int64_t nfunctions,int64_t noutervalues,
|
||||
int64_t nlineinfos,int64_t nlocalvarinfos,int64_t ndefaultparams)
|
||||
{
|
||||
SQFunctionProto *f;
|
||||
//I compact the whole class and members in a single memory allocation
|
||||
f = (SQFunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams));
|
||||
new (f) SQFunctionProto(ss);
|
||||
f->_ninstructions = ninstructions;
|
||||
f->_literals = (rabbit::ObjectPtr*)&f->_instructions[ninstructions];
|
||||
f->_nliterals = nliterals;
|
||||
f->_parameters = (rabbit::ObjectPtr*)&f->_literals[nliterals];
|
||||
f->_nparameters = nparameters;
|
||||
f->_functions = (rabbit::ObjectPtr*)&f->_parameters[nparameters];
|
||||
f->_nfunctions = nfunctions;
|
||||
f->_outervalues = (SQOuterVar*)&f->_functions[nfunctions];
|
||||
f->_noutervalues = noutervalues;
|
||||
f->_lineinfos = (SQLineInfo *)&f->_outervalues[noutervalues];
|
||||
f->_nlineinfos = nlineinfos;
|
||||
f->_localvarinfos = (SQLocalVarInfo *)&f->_lineinfos[nlineinfos];
|
||||
f->_nlocalvarinfos = nlocalvarinfos;
|
||||
f->_defaultparams = (int64_t *)&f->_localvarinfos[nlocalvarinfos];
|
||||
f->_ndefaultparams = ndefaultparams;
|
||||
|
||||
_CONSTRUCT_VECTOR(rabbit::ObjectPtr,f->_nliterals,f->_literals);
|
||||
_CONSTRUCT_VECTOR(rabbit::ObjectPtr,f->_nparameters,f->_parameters);
|
||||
_CONSTRUCT_VECTOR(rabbit::ObjectPtr,f->_nfunctions,f->_functions);
|
||||
_CONSTRUCT_VECTOR(SQOuterVar,f->_noutervalues,f->_outervalues);
|
||||
//_CONSTRUCT_VECTOR(SQLineInfo,f->_nlineinfos,f->_lineinfos); //not required are 2 integers
|
||||
_CONSTRUCT_VECTOR(SQLocalVarInfo,f->_nlocalvarinfos,f->_localvarinfos);
|
||||
return f;
|
||||
}
|
||||
void release(){
|
||||
_DESTRUCT_VECTOR(ObjectPtr,_nliterals,_literals);
|
||||
_DESTRUCT_VECTOR(ObjectPtr,_nparameters,_parameters);
|
||||
_DESTRUCT_VECTOR(ObjectPtr,_nfunctions,_functions);
|
||||
_DESTRUCT_VECTOR(SQOuterVar,_noutervalues,_outervalues);
|
||||
//_DESTRUCT_VECTOR(SQLineInfo,_nlineinfos,_lineinfos); //not required are 2 integers
|
||||
_DESTRUCT_VECTOR(SQLocalVarInfo,_nlocalvarinfos,_localvarinfos);
|
||||
int64_t size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos,_ndefaultparams);
|
||||
this->~SQFunctionProto();
|
||||
sq_vm_free(this,size);
|
||||
}
|
||||
|
||||
const rabbit::Char* getLocal(rabbit::VirtualMachine *v,uint64_t stackbase,uint64_t nseq,uint64_t nop);
|
||||
int64_t getLine(SQInstruction *curr);
|
||||
bool save(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQWRITEFUNC write);
|
||||
static bool load(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQREADFUNC read,rabbit::ObjectPtr &ret);
|
||||
rabbit::ObjectPtr _sourcename;
|
||||
rabbit::ObjectPtr _name;
|
||||
int64_t _stacksize;
|
||||
bool _bgenerator;
|
||||
int64_t _varparams;
|
||||
|
||||
int64_t _nlocalvarinfos;
|
||||
SQLocalVarInfo *_localvarinfos;
|
||||
|
||||
int64_t _nlineinfos;
|
||||
SQLineInfo *_lineinfos;
|
||||
|
||||
int64_t _nliterals;
|
||||
rabbit::ObjectPtr *_literals;
|
||||
|
||||
int64_t _nparameters;
|
||||
rabbit::ObjectPtr *_parameters;
|
||||
|
||||
int64_t _nfunctions;
|
||||
rabbit::ObjectPtr *_functions;
|
||||
|
||||
int64_t _noutervalues;
|
||||
SQOuterVar *_outervalues;
|
||||
|
||||
int64_t _ndefaultparams;
|
||||
int64_t *_defaultparams;
|
||||
|
||||
int64_t _ninstructions;
|
||||
SQInstruction _instructions[1];
|
||||
};
|
@ -1,94 +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>
|
||||
|
||||
struct SQFuncState
|
||||
{
|
||||
SQFuncState(rabbit::SharedState *ss,SQFuncState *parent,compilererrorFunc efunc,void *ed);
|
||||
~SQFuncState();
|
||||
#ifdef _DEBUG_DUMP
|
||||
void dump(SQFunctionProto *func);
|
||||
#endif
|
||||
void error(const rabbit::Char *err);
|
||||
SQFuncState *pushChildState(rabbit::SharedState *ss);
|
||||
void popChildState();
|
||||
void addInstruction(SQOpcode _op,int64_t arg0=0,int64_t arg1=0,int64_t arg2=0,int64_t arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);addInstruction(i);}
|
||||
void addInstruction(SQInstruction &i);
|
||||
void setIntructionParams(int64_t pos,int64_t arg0,int64_t arg1,int64_t arg2=0,int64_t arg3=0);
|
||||
void setIntructionParam(int64_t pos,int64_t arg,int64_t val);
|
||||
SQInstruction &getInstruction(int64_t pos){return _instructions[pos];}
|
||||
void popInstructions(int64_t size){for(int64_t i=0;i<size;i++)_instructions.popBack();}
|
||||
void setStacksize(int64_t n);
|
||||
int64_t CountOuters(int64_t stacksize);
|
||||
void snoozeOpt(){_optimization=false;}
|
||||
void addDefaultParam(int64_t trg) { _defaultparams.pushBack(trg); }
|
||||
int64_t getDefaultParamCount() { return _defaultparams.size(); }
|
||||
int64_t getCurrentPos(){return _instructions.size()-1;}
|
||||
int64_t getNumericConstant(const int64_t cons);
|
||||
int64_t getNumericConstant(const float_t cons);
|
||||
int64_t pushLocalVariable(const rabbit::Object &name);
|
||||
void addParameter(const rabbit::Object &name);
|
||||
//void addOuterValue(const rabbit::Object &name);
|
||||
int64_t getLocalVariable(const rabbit::Object &name);
|
||||
void markLocalAsOuter(int64_t pos);
|
||||
int64_t getOuterVariable(const rabbit::Object &name);
|
||||
int64_t generateCode();
|
||||
int64_t getStacksize();
|
||||
int64_t calcStackFramesize();
|
||||
void addLineInfos(int64_t line,bool lineop,bool force=false);
|
||||
SQFunctionProto *buildProto();
|
||||
int64_t allocStackPos();
|
||||
int64_t pushTarget(int64_t n=-1);
|
||||
int64_t popTarget();
|
||||
int64_t topTarget();
|
||||
int64_t getUpTarget(int64_t n);
|
||||
void discardTarget();
|
||||
bool isLocal(uint64_t stkpos);
|
||||
rabbit::Object createString(const rabbit::Char *s,int64_t len = -1);
|
||||
rabbit::Object createTable();
|
||||
bool isConstant(const rabbit::Object &name,rabbit::Object &e);
|
||||
int64_t _returnexp;
|
||||
SQLocalVarInfoVec _vlocals;
|
||||
etk::Vector<int64_t> _targetstack;
|
||||
int64_t _stacksize;
|
||||
bool _varparams;
|
||||
bool _bgenerator;
|
||||
etk::Vector<int64_t> _unresolvedbreaks;
|
||||
etk::Vector<int64_t> _unresolvedcontinues;
|
||||
etk::Vector<rabbit::ObjectPtr> _functions;
|
||||
etk::Vector<rabbit::ObjectPtr> _parameters;
|
||||
SQOuterVarVec _outervalues;
|
||||
SQInstructionVec _instructions;
|
||||
SQLocalVarInfoVec _localvarinfos;
|
||||
rabbit::ObjectPtr _literals;
|
||||
rabbit::ObjectPtr _strings;
|
||||
rabbit::ObjectPtr _name;
|
||||
rabbit::ObjectPtr _sourcename;
|
||||
int64_t _nliterals;
|
||||
SQLineInfoVec _lineinfos;
|
||||
SQFuncState *_parent;
|
||||
etk::Vector<int64_t> _scope_blocks;
|
||||
etk::Vector<int64_t> _breaktargets;
|
||||
etk::Vector<int64_t> _continuetargets;
|
||||
etk::Vector<int64_t> _defaultparams;
|
||||
int64_t _lastline;
|
||||
int64_t _traps; //contains number of nested exception traps
|
||||
int64_t _outers;
|
||||
bool _optimization;
|
||||
rabbit::SharedState *_sharedstate;
|
||||
etk::Vector<SQFuncState*> _childstates;
|
||||
int64_t getConstant(const rabbit::Object &cons);
|
||||
private:
|
||||
compilererrorFunc _errfunc;
|
||||
void *_errtarget;
|
||||
rabbit::SharedState *_ss;
|
||||
};
|
||||
|
||||
|
@ -1,59 +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
|
||||
|
||||
#ifdef SQUNICODE
|
||||
typedef rabbit::Char LexChar;
|
||||
#else
|
||||
typedef unsigned char LexChar;
|
||||
#endif
|
||||
|
||||
struct SQLexer
|
||||
{
|
||||
SQLexer();
|
||||
~SQLexer();
|
||||
void init(rabbit::SharedState *ss,SQLEXREADFUNC rg,rabbit::UserPointer up,compilererrorFunc efunc,void *ed);
|
||||
void error(const rabbit::Char *err);
|
||||
int64_t Lex();
|
||||
const rabbit::Char *tok2Str(int64_t tok);
|
||||
private:
|
||||
int64_t getIDType(const rabbit::Char *s,int64_t len);
|
||||
int64_t readString(int64_t ndelim,bool verbatim);
|
||||
int64_t readNumber();
|
||||
void lexBlockComment();
|
||||
void lexLineComment();
|
||||
int64_t readId();
|
||||
void next();
|
||||
#ifdef SQUNICODE
|
||||
#if WCHAR_SIZE == 2
|
||||
int64_t addUTF16(uint64_t ch);
|
||||
#endif
|
||||
#else
|
||||
int64_t addUTF8(uint64_t ch);
|
||||
#endif
|
||||
int64_t processStringHexEscape(rabbit::Char *dest, int64_t maxdigits);
|
||||
int64_t _curtoken;
|
||||
rabbit::Table *_keywords;
|
||||
rabbit::Bool _reached_eof;
|
||||
public:
|
||||
int64_t _prevtoken;
|
||||
int64_t _currentline;
|
||||
int64_t _lasttokenline;
|
||||
int64_t _currentcolumn;
|
||||
const rabbit::Char *_svalue;
|
||||
int64_t _nvalue;
|
||||
float_t _fvalue;
|
||||
SQLEXREADFUNC _readf;
|
||||
rabbit::UserPointer _up;
|
||||
LexChar _currdata;
|
||||
rabbit::SharedState *_sharedstate;
|
||||
etk::Vector<rabbit::Char> _longstr;
|
||||
compilererrorFunc _errfunc;
|
||||
void *_errtarget;
|
||||
};
|
||||
|
@ -1,433 +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/VirtualMachine.hpp>
|
||||
|
||||
#include <rabbit/Array.hpp>
|
||||
|
||||
#include <rabbit/UserData.hpp>
|
||||
#include <rabbit/sqfuncproto.hpp>
|
||||
|
||||
#include <rabbit/sqclosure.hpp>
|
||||
|
||||
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==eDead) { v->raise_error(_SC("internal vm error, yielding a dead generator")); return false; }
|
||||
int64_t size = v->_top-v->_stackbase;
|
||||
|
||||
_stack.resize(size);
|
||||
rabbit::Object _this = v->_stack[v->_stackbase];
|
||||
_stack[0] = ISREFCOUNTED(sq_type(_this)) ? rabbit::ObjectPtr(_refcounted(_this)->getWeakRef(sq_type(_this))) : _this;
|
||||
for(int64_t n =1; n<target; n++) {
|
||||
_stack[n] = v->_stack[v->_stackbase+n];
|
||||
}
|
||||
for(int64_t j =0; j < size; j++)
|
||||
{
|
||||
v->_stack[v->_stackbase+j].Null();
|
||||
}
|
||||
|
||||
_ci = *v->ci;
|
||||
_ci._generator=NULL;
|
||||
for(int64_t i=0;i<_ci._etraps;i++) {
|
||||
_etraps.pushBack(v->_etraps.back());
|
||||
v->_etraps.popBack();
|
||||
// store relative stack base and size in case of resume to other _top
|
||||
rabbit::ExceptionTrap &et = _etraps.back();
|
||||
et._stackbase -= v->_stackbase;
|
||||
et._stacksize -= v->_stackbase;
|
||||
}
|
||||
_state=eSuspended;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SQGenerator::resume(rabbit::VirtualMachine *v,rabbit::ObjectPtr &dest)
|
||||
{
|
||||
if(_state==eDead){ v->raise_error(_SC("resuming dead generator")); return false; }
|
||||
if(_state==eRunning){ v->raise_error(_SC("resuming active generator")); return false; }
|
||||
int64_t size = _stack.size();
|
||||
int64_t target = &dest - &(v->_stack[v->_stackbase]);
|
||||
assert(target>=0 && target<=255);
|
||||
int64_t newbase = v->_top;
|
||||
if(!v->enterFrame(v->_top, v->_top + size, false))
|
||||
return false;
|
||||
v->ci->_generator = this;
|
||||
v->ci->_target = (int32_t)target;
|
||||
v->ci->_closure = _ci._closure;
|
||||
v->ci->_ip = _ci._ip;
|
||||
v->ci->_literals = _ci._literals;
|
||||
v->ci->_ncalls = _ci._ncalls;
|
||||
v->ci->_etraps = _ci._etraps;
|
||||
v->ci->_root = _ci._root;
|
||||
|
||||
|
||||
for(int64_t i=0;i<_ci._etraps;i++) {
|
||||
v->_etraps.pushBack(_etraps.back());
|
||||
_etraps.popBack();
|
||||
rabbit::ExceptionTrap &et = v->_etraps.back();
|
||||
// restore absolute stack base and size
|
||||
et._stackbase += newbase;
|
||||
et._stacksize += newbase;
|
||||
}
|
||||
rabbit::Object _this = _stack[0];
|
||||
v->_stack[v->_stackbase] = sq_type(_this) == rabbit::OT_WEAKREF ? _weakref(_this)->_obj : _this;
|
||||
|
||||
for(int64_t n = 1; n<size; n++) {
|
||||
v->_stack[v->_stackbase+n] = _stack[n];
|
||||
_stack[n].Null();
|
||||
}
|
||||
|
||||
_state=eRunning;
|
||||
if (v->_debughook)
|
||||
v->callDebugHook(_SC('c'));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void rabbit::Array::extend(const rabbit::Array *a){
|
||||
int64_t xlen;
|
||||
if((xlen=a->size()))
|
||||
for(int64_t i=0;i<xlen;i++)
|
||||
append((*a)[i]);
|
||||
}
|
||||
|
||||
const rabbit::Char* SQFunctionProto::getLocal(rabbit::VirtualMachine *vm,uint64_t stackbase,uint64_t nseq,uint64_t nop)
|
||||
{
|
||||
uint64_t nvars=_nlocalvarinfos;
|
||||
const rabbit::Char *res=NULL;
|
||||
if(nvars>=nseq){
|
||||
for(uint64_t i=0;i<nvars;i++){
|
||||
if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop)
|
||||
{
|
||||
if(nseq==0){
|
||||
vm->push(vm->_stack[stackbase+_localvarinfos[i]._pos]);
|
||||
res=_stringval(_localvarinfos[i]._name);
|
||||
break;
|
||||
}
|
||||
nseq--;
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int64_t SQFunctionProto::getLine(SQInstruction *curr)
|
||||
{
|
||||
int64_t op = (int64_t)(curr-_instructions);
|
||||
int64_t line=_lineinfos[0]._line;
|
||||
int64_t low = 0;
|
||||
int64_t high = _nlineinfos - 1;
|
||||
int64_t mid = 0;
|
||||
while(low <= high)
|
||||
{
|
||||
mid = low + ((high - low) >> 1);
|
||||
int64_t curop = _lineinfos[mid]._op;
|
||||
if(curop > op)
|
||||
{
|
||||
high = mid - 1;
|
||||
}
|
||||
else if(curop < op) {
|
||||
if(mid < (_nlineinfos - 1)
|
||||
&& _lineinfos[mid + 1]._op >= op) {
|
||||
break;
|
||||
}
|
||||
low = mid + 1;
|
||||
}
|
||||
else { //equal
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while(mid > 0 && _lineinfos[mid]._op >= op) mid--;
|
||||
|
||||
line = _lineinfos[mid]._line;
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
SQClosure::~SQClosure()
|
||||
{
|
||||
__Objrelease(_root);
|
||||
__Objrelease(_env);
|
||||
__Objrelease(_base);
|
||||
}
|
||||
|
||||
#define _CHECK_IO(exp) { if(!exp)return false; }
|
||||
bool SafeWrite(rabbit::VirtualMachine* v,SQWRITEFUNC write,rabbit::UserPointer up,rabbit::UserPointer dest,int64_t size)
|
||||
{
|
||||
if(write(up,dest,size) != size) {
|
||||
v->raise_error(_SC("io error (write function failure)"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SafeRead(rabbit::VirtualMachine* v,SQWRITEFUNC read,rabbit::UserPointer up,rabbit::UserPointer dest,int64_t size)
|
||||
{
|
||||
if(size && read(up,dest,size) != size) {
|
||||
v->raise_error(_SC("io error, read function failure, the origin stream could be corrupted/trucated"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteTag(rabbit::VirtualMachine* v,SQWRITEFUNC write,rabbit::UserPointer up,uint32_t tag)
|
||||
{
|
||||
return SafeWrite(v,write,up,&tag,sizeof(tag));
|
||||
}
|
||||
|
||||
bool CheckTag(rabbit::VirtualMachine* v,SQWRITEFUNC read,rabbit::UserPointer up,uint32_t tag)
|
||||
{
|
||||
uint32_t t;
|
||||
_CHECK_IO(SafeRead(v,read,up,&t,sizeof(t)));
|
||||
if(t != tag){
|
||||
v->raise_error(_SC("invalid or corrupted closure stream"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteObject(rabbit::VirtualMachine* v,rabbit::UserPointer up,SQWRITEFUNC write,rabbit::ObjectPtr &o)
|
||||
{
|
||||
uint32_t _type = (uint32_t)sq_type(o);
|
||||
_CHECK_IO(SafeWrite(v,write,up,&_type,sizeof(_type)));
|
||||
switch(sq_type(o)){
|
||||
case rabbit::OT_STRING:
|
||||
_CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(int64_t)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,_stringval(o),sq_rsl(_string(o)->_len)));
|
||||
break;
|
||||
case rabbit::OT_BOOL:
|
||||
case rabbit::OT_INTEGER:
|
||||
_CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(int64_t)));break;
|
||||
case rabbit::OT_FLOAT:
|
||||
_CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(float_t)));break;
|
||||
case rabbit::OT_NULL:
|
||||
break;
|
||||
default:
|
||||
v->raise_error(_SC("cannot serialize a %s"),getTypeName(o));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReadObject(rabbit::VirtualMachine* v,rabbit::UserPointer up,SQREADFUNC read,rabbit::ObjectPtr &o)
|
||||
{
|
||||
uint32_t _type;
|
||||
_CHECK_IO(SafeRead(v,read,up,&_type,sizeof(_type)));
|
||||
rabbit::ObjectType t = (rabbit::ObjectType)_type;
|
||||
switch(t){
|
||||
case rabbit::OT_STRING:{
|
||||
int64_t len;
|
||||
_CHECK_IO(SafeRead(v,read,up,&len,sizeof(int64_t)));
|
||||
_CHECK_IO(SafeRead(v,read,up,_get_shared_state(v)->getScratchPad(sq_rsl(len)),sq_rsl(len)));
|
||||
o=rabbit::String::create(_get_shared_state(v),_get_shared_state(v)->getScratchPad(-1),len);
|
||||
}
|
||||
break;
|
||||
case rabbit::OT_INTEGER:{
|
||||
int64_t i;
|
||||
_CHECK_IO(SafeRead(v,read,up,&i,sizeof(int64_t))); o = i; break;
|
||||
}
|
||||
case rabbit::OT_BOOL:{
|
||||
int64_t i;
|
||||
_CHECK_IO(SafeRead(v,read,up,&i,sizeof(int64_t))); o._type = rabbit::OT_BOOL; o._unVal.nInteger = i; break;
|
||||
}
|
||||
case rabbit::OT_FLOAT:{
|
||||
float_t f;
|
||||
_CHECK_IO(SafeRead(v,read,up,&f,sizeof(float_t))); o = f; break;
|
||||
}
|
||||
case rabbit::OT_NULL:
|
||||
o.Null();
|
||||
break;
|
||||
default:
|
||||
v->raise_error(_SC("cannot serialize a %s"),IdType2Name(t));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SQClosure::save(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQWRITEFUNC write)
|
||||
{
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD));
|
||||
_CHECK_IO(WriteTag(v,write,up,sizeof(rabbit::Char)));
|
||||
_CHECK_IO(WriteTag(v,write,up,sizeof(int64_t)));
|
||||
_CHECK_IO(WriteTag(v,write,up,sizeof(float_t)));
|
||||
_CHECK_IO(_function->save(v,up,write));
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SQClosure::load(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQREADFUNC read,rabbit::ObjectPtr &ret)
|
||||
{
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD));
|
||||
_CHECK_IO(CheckTag(v,read,up,sizeof(rabbit::Char)));
|
||||
_CHECK_IO(CheckTag(v,read,up,sizeof(int64_t)));
|
||||
_CHECK_IO(CheckTag(v,read,up,sizeof(float_t)));
|
||||
rabbit::ObjectPtr func;
|
||||
_CHECK_IO(SQFunctionProto::load(v,up,read,func));
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL));
|
||||
ret = SQClosure::create(_get_shared_state(v),_funcproto(func),_table(v->_roottable)->getWeakRef(rabbit::OT_TABLE));
|
||||
//FIXME: load an root for this closure
|
||||
return true;
|
||||
}
|
||||
|
||||
SQFunctionProto::SQFunctionProto(rabbit::SharedState *ss)
|
||||
{
|
||||
_stacksize=0;
|
||||
_bgenerator=false;
|
||||
}
|
||||
|
||||
SQFunctionProto::~SQFunctionProto()
|
||||
{
|
||||
}
|
||||
|
||||
bool SQFunctionProto::save(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQWRITEFUNC write)
|
||||
{
|
||||
int64_t i,nliterals = _nliterals,nparameters = _nparameters;
|
||||
int64_t noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos;
|
||||
int64_t nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions;
|
||||
int64_t ndefaultparams = _ndefaultparams;
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
|
||||
_CHECK_IO(WriteObject(v,up,write,_sourcename));
|
||||
_CHECK_IO(WriteObject(v,up,write,_name));
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&nliterals,sizeof(nliterals)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&nparameters,sizeof(nparameters)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&ndefaultparams,sizeof(ndefaultparams)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions)));
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
|
||||
for(i=0;i<nliterals;i++){
|
||||
_CHECK_IO(WriteObject(v,up,write,_literals[i]));
|
||||
}
|
||||
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
|
||||
for(i=0;i<nparameters;i++){
|
||||
_CHECK_IO(WriteObject(v,up,write,_parameters[i]));
|
||||
}
|
||||
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
|
||||
for(i=0;i<noutervalues;i++){
|
||||
_CHECK_IO(SafeWrite(v,write,up,&_outervalues[i]._type,sizeof(uint64_t)));
|
||||
_CHECK_IO(WriteObject(v,up,write,_outervalues[i]._src));
|
||||
_CHECK_IO(WriteObject(v,up,write,_outervalues[i]._name));
|
||||
}
|
||||
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
|
||||
for(i=0;i<nlocalvarinfos;i++){
|
||||
SQLocalVarInfo &lvi=_localvarinfos[i];
|
||||
_CHECK_IO(WriteObject(v,up,write,lvi._name));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&lvi._pos,sizeof(uint64_t)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&lvi._start_op,sizeof(uint64_t)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&lvi._end_op,sizeof(uint64_t)));
|
||||
}
|
||||
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
|
||||
_CHECK_IO(SafeWrite(v,write,up,_lineinfos,sizeof(SQLineInfo)*nlineinfos));
|
||||
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
|
||||
_CHECK_IO(SafeWrite(v,write,up,_defaultparams,sizeof(int64_t)*ndefaultparams));
|
||||
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
|
||||
_CHECK_IO(SafeWrite(v,write,up,_instructions,sizeof(SQInstruction)*ninstructions));
|
||||
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
|
||||
for(i=0;i<nfunctions;i++){
|
||||
_CHECK_IO(_funcproto(_functions[i])->save(v,up,write));
|
||||
}
|
||||
_CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams)));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SQFunctionProto::load(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQREADFUNC read,rabbit::ObjectPtr &ret)
|
||||
{
|
||||
int64_t i, nliterals,nparameters;
|
||||
int64_t noutervalues ,nlocalvarinfos ;
|
||||
int64_t nlineinfos,ninstructions ,nfunctions,ndefaultparams ;
|
||||
rabbit::ObjectPtr sourcename, name;
|
||||
rabbit::ObjectPtr o;
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
|
||||
_CHECK_IO(ReadObject(v, up, read, sourcename));
|
||||
_CHECK_IO(ReadObject(v, up, read, name));
|
||||
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
|
||||
_CHECK_IO(SafeRead(v,read,up, &nliterals, sizeof(nliterals)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &nparameters, sizeof(nparameters)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &noutervalues, sizeof(noutervalues)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &nlocalvarinfos, sizeof(nlocalvarinfos)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &nlineinfos, sizeof(nlineinfos)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &ndefaultparams, sizeof(ndefaultparams)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &ninstructions, sizeof(ninstructions)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions)));
|
||||
|
||||
|
||||
SQFunctionProto *f = SQFunctionProto::create(NULL,ninstructions,nliterals,nparameters,
|
||||
nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams);
|
||||
rabbit::ObjectPtr proto = f; //gets a ref in case of failure
|
||||
f->_sourcename = sourcename;
|
||||
f->_name = name;
|
||||
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
|
||||
|
||||
for(i = 0;i < nliterals; i++){
|
||||
_CHECK_IO(ReadObject(v, up, read, o));
|
||||
f->_literals[i] = o;
|
||||
}
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
|
||||
|
||||
for(i = 0; i < nparameters; i++){
|
||||
_CHECK_IO(ReadObject(v, up, read, o));
|
||||
f->_parameters[i] = o;
|
||||
}
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
|
||||
|
||||
for(i = 0; i < noutervalues; i++){
|
||||
uint64_t type;
|
||||
rabbit::ObjectPtr name;
|
||||
_CHECK_IO(SafeRead(v,read,up, &type, sizeof(uint64_t)));
|
||||
_CHECK_IO(ReadObject(v, up, read, o));
|
||||
_CHECK_IO(ReadObject(v, up, read, name));
|
||||
f->_outervalues[i] = SQOuterVar(name,o, (SQOuterType)type);
|
||||
}
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
|
||||
|
||||
for(i = 0; i < nlocalvarinfos; i++){
|
||||
SQLocalVarInfo lvi;
|
||||
_CHECK_IO(ReadObject(v, up, read, lvi._name));
|
||||
_CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(uint64_t)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(uint64_t)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(uint64_t)));
|
||||
f->_localvarinfos[i] = lvi;
|
||||
}
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
|
||||
_CHECK_IO(SafeRead(v,read,up, f->_lineinfos, sizeof(SQLineInfo)*nlineinfos));
|
||||
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
|
||||
_CHECK_IO(SafeRead(v,read,up, f->_defaultparams, sizeof(int64_t)*ndefaultparams));
|
||||
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
|
||||
_CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(SQInstruction)*ninstructions));
|
||||
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
|
||||
for(i = 0; i < nfunctions; i++){
|
||||
_CHECK_IO(_funcproto(o)->load(v, up, read, o));
|
||||
f->_functions[i] = o;
|
||||
}
|
||||
_CHECK_IO(SafeRead(v,read,up, &f->_stacksize, sizeof(f->_stacksize)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &f->_bgenerator, sizeof(f->_bgenerator)));
|
||||
_CHECK_IO(SafeRead(v,read,up, &f->_varparams, sizeof(f->_varparams)));
|
||||
|
||||
ret = f;
|
||||
return true;
|
||||
}
|
||||
|
@ -1,46 +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/RefCounted.hpp>
|
||||
#include <rabbit/WeakRef.hpp>
|
||||
|
||||
#ifdef _SQ64
|
||||
#define UINT_MINUS_ONE (0xFFFFFFFFFFFFFFFF)
|
||||
#else
|
||||
#define UINT_MINUS_ONE (0xFFFFFFFF)
|
||||
#endif
|
||||
|
||||
#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R'))
|
||||
#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T'))
|
||||
#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L'))
|
||||
|
||||
#define _CONSTRUCT_VECTOR(type, size, ptr) { \
|
||||
for(int64_t n = 0; n < ((int64_t)size); n++) { \
|
||||
new (&ptr[n]) type(); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define _DESTRUCT_VECTOR(type, size, ptr) { \
|
||||
for(int64_t nl = 0; nl < ((int64_t)size); nl++) { \
|
||||
ptr[nl].~type(); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define _COPY_VECTOR(dest, src, size) { \
|
||||
for(int64_t _n_ = 0; _n_ < ((int64_t)size); _n_++) { \
|
||||
dest[_n_] = src[_n_]; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define _NULL_SQOBJECT_VECTOR(vec, size) { \
|
||||
for(int64_t _n_ = 0; _n_ < ((int64_t)size); _n_++) { \
|
||||
vec[_n_].Null(); \
|
||||
} \
|
||||
}
|
@ -107,14 +107,14 @@ enum SQOpcode
|
||||
_OP_CLOSE= 0x3C
|
||||
};
|
||||
|
||||
struct SQInstructionDesc {
|
||||
struct rabbit::InstructionDesc {
|
||||
const rabbit::Char *name;
|
||||
};
|
||||
|
||||
struct SQInstruction
|
||||
struct rabbit::Instruction
|
||||
{
|
||||
SQInstruction(){};
|
||||
SQInstruction(SQOpcode _op,int64_t a0=0,int64_t a1=0,int64_t a2=0,int64_t a3=0)
|
||||
rabbit::Instruction(){};
|
||||
rabbit::Instruction(SQOpcode _op,int64_t a0=0,int64_t a1=0,int64_t a2=0,int64_t a3=0)
|
||||
{ op = (unsigned char)_op;
|
||||
_arg0 = (unsigned char)a0;_arg1 = (int32_t)a1;
|
||||
_arg2 = (unsigned char)a2;_arg3 = (unsigned char)a3;
|
||||
@ -129,7 +129,7 @@ struct SQInstruction
|
||||
};
|
||||
|
||||
#include <rabbit/squtils.hpp>
|
||||
typedef etk::Vector<SQInstruction> SQInstructionVec;
|
||||
typedef etk::Vector<rabbit::Instruction> rabbit::InstructionVec;
|
||||
|
||||
#define NEW_SLOT_ATTRIBUTES_FLAG 0x01
|
||||
#define NEW_SLOT_STATIC_FLAG 0x02
|
||||
|
@ -1,24 +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
|
||||
|
||||
#if defined(_MSC_VER) && defined(_DEBUG)
|
||||
#include <crtdbg.hpp>
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <new>
|
||||
//rabbit stuff
|
||||
#include <rabbit/rabbit.hpp>
|
||||
#include <rabbit/sqobject.hpp>
|
||||
|
||||
|
@ -21,5 +21,28 @@ void sq_vm_free(void *p,uint64_t size);
|
||||
#define sq_aligning(v) (((size_t)(v) + (SQ_ALIGNMENT-1)) & (~(SQ_ALIGNMENT-1)))
|
||||
|
||||
|
||||
#include <etk/Vector.hpp>
|
||||
|
||||
#define _CONSTRUCT_VECTOR(type, size, ptr) { \
|
||||
for(int64_t n = 0; n < ((int64_t)size); n++) { \
|
||||
new (&ptr[n]) type(); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define _DESTRUCT_VECTOR(type, size, ptr) { \
|
||||
for(int64_t nl = 0; nl < ((int64_t)size); nl++) { \
|
||||
ptr[nl].~type(); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define _COPY_VECTOR(dest, src, size) { \
|
||||
for(int64_t _n_ = 0; _n_ < ((int64_t)size); _n_++) { \
|
||||
dest[_n_] = src[_n_]; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define _NULL_SQOBJECT_VECTOR(vec, size) { \
|
||||
for(int64_t _n_ = 0; _n_ < ((int64_t)size); _n_++) { \
|
||||
vec[_n_].Null(); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user