From aa49dbd05dd08b5dbe032f9109d3002a3ae4821e Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Fri, 29 Jun 2018 00:11:33 +0200 Subject: [PATCH] [DEV] continue rework (main step) --- lutin_rabbit-core.py | 177 +++++---- rabbit/Closure.cpp | 135 +++++++ rabbit/Closure.hpp | 76 ++++ rabbit/{sqcompiler.cpp => Compiler.cpp} | 66 ++-- rabbit/Compiler.hpp | 84 +++++ rabbit/ExceptionTrap.hpp | 6 +- rabbit/{sqfuncstate.cpp => FuncState.cpp} | 116 +++--- rabbit/FuncState.hpp | 92 +++++ rabbit/FunctionProto.cpp | 224 +++++++++++ rabbit/FunctionProto.hpp | 105 ++++++ rabbit/Generator.cpp | 87 +++++ rabbit/Generator.hpp | 47 +++ rabbit/Instruction.cpp | 9 + rabbit/Instruction.hpp | 12 + rabbit/{sqlexer.cpp => Lexer.cpp} | 37 +- rabbit/Lexer.hpp | 61 +++ rabbit/LineInfo.cpp | 9 + rabbit/LineInfo.hpp | 16 + rabbit/LocalVarInfo.cpp | 9 + rabbit/LocalVarInfo.hpp | 26 ++ rabbit/MetaMethod | 0 rabbit/NativeClosure.cpp | 9 + rabbit/NativeClosure.hpp | 63 ++++ rabbit/ObjectPtr.cpp | 10 +- rabbit/ObjectPtr.hpp | 10 +- rabbit/ObjectValue.hpp | 10 +- rabbit/Outer.cpp | 9 + rabbit/Outer.hpp | 37 ++ rabbit/OuterVar.cpp | 9 + rabbit/OuterVar.hpp | 34 ++ rabbit/RefTable.cpp | 4 +- rabbit/SharedState.cpp | 9 +- rabbit/SharedState.hpp | 2 + rabbit/VirtualMachine.cpp | 58 +-- rabbit/VirtualMachine.hpp | 14 +- rabbit/sqapi.cpp | 36 +- rabbit/sqbaselib.cpp | 10 +- rabbit/sqclosure.hpp | 196 ---------- rabbit/sqcompiler.hpp | 84 ----- rabbit/sqconfig.hpp | 20 +- rabbit/sqdebug.cpp | 6 +- rabbit/sqfuncproto.hpp | 152 -------- rabbit/sqfuncstate.hpp | 94 ----- rabbit/sqlexer.hpp | 59 --- rabbit/sqobject.cpp | 433 ---------------------- rabbit/sqobject.hpp | 46 --- rabbit/sqopcodes.hpp | 10 +- rabbit/sqpcheader.hpp | 24 -- rabbit/squtils.hpp | 25 +- 49 files changed, 1495 insertions(+), 1372 deletions(-) create mode 100644 rabbit/Closure.cpp create mode 100644 rabbit/Closure.hpp rename rabbit/{sqcompiler.cpp => Compiler.cpp} (95%) create mode 100644 rabbit/Compiler.hpp rename rabbit/{sqfuncstate.cpp => FuncState.cpp} (81%) create mode 100644 rabbit/FuncState.hpp create mode 100644 rabbit/FunctionProto.cpp create mode 100644 rabbit/FunctionProto.hpp create mode 100644 rabbit/Generator.cpp create mode 100644 rabbit/Generator.hpp create mode 100644 rabbit/Instruction.cpp create mode 100644 rabbit/Instruction.hpp rename rabbit/{sqlexer.cpp => Lexer.cpp} (94%) create mode 100644 rabbit/Lexer.hpp create mode 100644 rabbit/LineInfo.cpp create mode 100644 rabbit/LineInfo.hpp create mode 100644 rabbit/LocalVarInfo.cpp create mode 100644 rabbit/LocalVarInfo.hpp delete mode 100644 rabbit/MetaMethod create mode 100644 rabbit/NativeClosure.cpp create mode 100644 rabbit/NativeClosure.hpp create mode 100644 rabbit/Outer.cpp create mode 100644 rabbit/Outer.hpp create mode 100644 rabbit/OuterVar.cpp create mode 100644 rabbit/OuterVar.hpp delete mode 100644 rabbit/sqclosure.hpp delete mode 100644 rabbit/sqcompiler.hpp delete mode 100644 rabbit/sqfuncproto.hpp delete mode 100644 rabbit/sqfuncstate.hpp delete mode 100644 rabbit/sqlexer.hpp delete mode 100644 rabbit/sqobject.cpp delete mode 100644 rabbit/sqobject.hpp delete mode 100644 rabbit/sqpcheader.hpp diff --git a/lutin_rabbit-core.py b/lutin_rabbit-core.py index b243d3a..fdac9cf 100644 --- a/lutin_rabbit-core.py +++ b/lutin_rabbit-core.py @@ -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 diff --git a/rabbit/Closure.cpp b/rabbit/Closure.cpp new file mode 100644 index 0000000..4168418 --- /dev/null +++ b/rabbit/Closure.cpp @@ -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 + + + +#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); +} diff --git a/rabbit/Closure.hpp b/rabbit/Closure.hpp new file mode 100644 index 0000000..f614d0a --- /dev/null +++ b/rabbit/Closure.hpp @@ -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')) diff --git a/rabbit/sqcompiler.cpp b/rabbit/Compiler.cpp similarity index 95% rename from rabbit/sqcompiler.cpp rename to rabbit/Compiler.cpp index dde90d8..220549c 100644 --- a/rabbit/sqcompiler.cpp +++ b/rabbit/Compiler.cpp @@ -5,6 +5,8 @@ * @copyright 2003-2017, Alberto DEMICHELIS, all right reserved * @license MPL-2 (see license file) */ +#include + #include #ifndef NO_COMPILER #include @@ -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); } diff --git a/rabbit/Compiler.hpp b/rabbit/Compiler.hpp new file mode 100644 index 0000000..1c37387 --- /dev/null +++ b/rabbit/Compiler.hpp @@ -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); + +} \ No newline at end of file diff --git a/rabbit/ExceptionTrap.hpp b/rabbit/ExceptionTrap.hpp index 53cdc82..a4617c3 100644 --- a/rabbit/ExceptionTrap.hpp +++ b/rabbit/ExceptionTrap.hpp @@ -10,7 +10,7 @@ #include #include -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; }; } diff --git a/rabbit/sqfuncstate.cpp b/rabbit/FuncState.cpp similarity index 81% rename from rabbit/sqfuncstate.cpp rename to rabbit/FuncState.cpp index 2911dfe..bb16f3e 100644 --- a/rabbit/sqfuncstate.cpp +++ b/rabbit/FuncState.cpp @@ -5,18 +5,18 @@ * @copyright 2003-2017, Alberto DEMICHELIS, all right reserved * @license MPL-2 (see license file) */ +#include -#include #ifndef NO_COMPILER -#include +#include -#include +#include #include #include #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_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; igetOuterVariable(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) { diff --git a/rabbit/FuncState.hpp b/rabbit/FuncState.hpp new file mode 100644 index 0000000..08ce6ca --- /dev/null +++ b/rabbit/FuncState.hpp @@ -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 _vlocals; + etk::Vector _targetstack; + int64_t _stacksize; + bool _varparams; + bool _bgenerator; + etk::Vector _unresolvedbreaks; + etk::Vector _unresolvedcontinues; + etk::Vector _functions; + etk::Vector _parameters; + etk::Vector _outervalues; + rabbit::InstructionVec _instructions; + etk::Vector _localvarinfos; + rabbit::ObjectPtr _literals; + rabbit::ObjectPtr _strings; + rabbit::ObjectPtr _name; + rabbit::ObjectPtr _sourcename; + int64_t _nliterals; + etk::Vector _lineinfos; + FuncState *_parent; + etk::Vector _scope_blocks; + etk::Vector _breaktargets; + etk::Vector _continuetargets; + etk::Vector _defaultparams; + int64_t _lastline; + int64_t _traps; //contains number of nested exception traps + int64_t _outers; + bool _optimization; + rabbit::SharedState *_sharedstate; + etk::Vector _childstates; + int64_t getConstant(const rabbit::Object &cons); + private: + compilererrorFunc _errfunc; + void *_errtarget; + rabbit::SharedState *_ss; + }; +} diff --git a/rabbit/FunctionProto.cpp b/rabbit/FunctionProto.cpp new file mode 100644 index 0000000..988d418 --- /dev/null +++ b/rabbit/FunctionProto.cpp @@ -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 + + +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=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;isave(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; +} + diff --git a/rabbit/FunctionProto.hpp b/rabbit/FunctionProto.hpp new file mode 100644 index 0000000..e52bbc4 --- /dev/null +++ b/rabbit/FunctionProto.hpp @@ -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]; + }; + +} diff --git a/rabbit/Generator.cpp b/rabbit/Generator.cpp new file mode 100644 index 0000000..c2ccf9b --- /dev/null +++ b/rabbit/Generator.cpp @@ -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 + + + + + + +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_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_stack[v->_stackbase+n] = _stack[n]; + _stack[n].Null(); + } + + _state=eRunning; + if (v->_debughook) + v->callDebugHook(_SC('c')); + + return true; +} diff --git a/rabbit/Generator.hpp b/rabbit/Generator.hpp new file mode 100644 index 0000000..1a17d61 --- /dev/null +++ b/rabbit/Generator.hpp @@ -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 _stack; + rabbit::VirtualMachine::callInfo _ci; + etk::Vector _etraps; + rabbit::GeneratorState _state; + }; + +} diff --git a/rabbit/Instruction.cpp b/rabbit/Instruction.cpp new file mode 100644 index 0000000..a28456c --- /dev/null +++ b/rabbit/Instruction.cpp @@ -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 + diff --git a/rabbit/Instruction.hpp b/rabbit/Instruction.hpp new file mode 100644 index 0000000..b403036 --- /dev/null +++ b/rabbit/Instruction.hpp @@ -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 { + +} diff --git a/rabbit/sqlexer.cpp b/rabbit/Lexer.cpp similarity index 94% rename from rabbit/sqlexer.cpp rename to rabbit/Lexer.cpp index e322c2b..efd3ffc 100644 --- a/rabbit/sqlexer.cpp +++ b/rabbit/Lexer.cpp @@ -5,10 +5,7 @@ * @copyright 2003-2017, Alberto DEMICHELIS, all right reserved * @license MPL-2 (see license file) */ - -#include -#include -#include +#include #include @@ -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(); diff --git a/rabbit/Lexer.hpp b/rabbit/Lexer.hpp new file mode 100644 index 0000000..3ca917c --- /dev/null +++ b/rabbit/Lexer.hpp @@ -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 _longstr; + compilererrorFunc _errfunc; + void *_errtarget; + }; +} diff --git a/rabbit/LineInfo.cpp b/rabbit/LineInfo.cpp new file mode 100644 index 0000000..7780bbf --- /dev/null +++ b/rabbit/LineInfo.cpp @@ -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 + diff --git a/rabbit/LineInfo.hpp b/rabbit/LineInfo.hpp new file mode 100644 index 0000000..95baca4 --- /dev/null +++ b/rabbit/LineInfo.hpp @@ -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; + }; +} diff --git a/rabbit/LocalVarInfo.cpp b/rabbit/LocalVarInfo.cpp new file mode 100644 index 0000000..0e6e04d --- /dev/null +++ b/rabbit/LocalVarInfo.cpp @@ -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 + diff --git a/rabbit/LocalVarInfo.hpp b/rabbit/LocalVarInfo.hpp new file mode 100644 index 0000000..423a045 --- /dev/null +++ b/rabbit/LocalVarInfo.hpp @@ -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; + }; +} diff --git a/rabbit/MetaMethod b/rabbit/MetaMethod deleted file mode 100644 index e69de29..0000000 diff --git a/rabbit/NativeClosure.cpp b/rabbit/NativeClosure.cpp new file mode 100644 index 0000000..13facd5 --- /dev/null +++ b/rabbit/NativeClosure.cpp @@ -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 + diff --git a/rabbit/NativeClosure.hpp b/rabbit/NativeClosure.hpp new file mode 100644 index 0000000..c2564db --- /dev/null +++ b/rabbit/NativeClosure.hpp @@ -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 + +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 _typecheck; + rabbit::ObjectPtr *_outervalues; + uint64_t _noutervalues; + rabbit::WeakRef *_env; + SQFUNCTION _function; + rabbit::ObjectPtr _name; + }; + +} + diff --git a/rabbit/ObjectPtr.cpp b/rabbit/ObjectPtr.cpp index 9f03390..0e163fa 100644 --- a/rabbit/ObjectPtr.cpp +++ b/rabbit/ObjectPtr.cpp @@ -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) diff --git a/rabbit/ObjectPtr.hpp b/rabbit/ObjectPtr.hpp index 2feac38..e5eba99 100644 --- a/rabbit/ObjectPtr.hpp +++ b/rabbit/ObjectPtr.hpp @@ -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) diff --git a/rabbit/ObjectValue.hpp b/rabbit/ObjectValue.hpp index 1a98eb2..26ce522 100644 --- a/rabbit/ObjectValue.hpp +++ b/rabbit/ObjectValue.hpp @@ -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; diff --git a/rabbit/Outer.cpp b/rabbit/Outer.cpp new file mode 100644 index 0000000..31ae146 --- /dev/null +++ b/rabbit/Outer.cpp @@ -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 + diff --git a/rabbit/Outer.hpp b/rabbit/Outer.hpp new file mode 100644 index 0000000..fc2cb60 --- /dev/null +++ b/rabbit/Outer.hpp @@ -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 */ + }; + +} diff --git a/rabbit/OuterVar.cpp b/rabbit/OuterVar.cpp new file mode 100644 index 0000000..dd05844 --- /dev/null +++ b/rabbit/OuterVar.cpp @@ -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 + diff --git a/rabbit/OuterVar.hpp b/rabbit/OuterVar.hpp new file mode 100644 index 0000000..9e5be55 --- /dev/null +++ b/rabbit/OuterVar.hpp @@ -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; + }; + +} diff --git a/rabbit/RefTable.cpp b/rabbit/RefTable.cpp index 4ae6d8f..6b7900d 100644 --- a/rabbit/RefTable.cpp +++ b/rabbit/RefTable.cpp @@ -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; diff --git a/rabbit/SharedState.cpp b/rabbit/SharedState.cpp index 7e47b2e..3cf6e45 100644 --- a/rabbit/SharedState.cpp +++ b/rabbit/SharedState.cpp @@ -5,18 +5,17 @@ * @copyright 2003-2017, Alberto DEMICHELIS, all right reserved * @license MPL-2 (see license file) */ -#pragma once - #include - - +#include +#include +#include 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)) diff --git a/rabbit/SharedState.hpp b/rabbit/SharedState.hpp index d863460..2892dd9 100644 --- a/rabbit/SharedState.hpp +++ b/rabbit/SharedState.hpp @@ -8,8 +8,10 @@ #pragma once #include +#include #include #include +#include namespace rabbit { class StringTable; diff --git a/rabbit/VirtualMachine.cpp b/rabbit/VirtualMachine.cpp index 1a0664a..4108a64 100644 --- a/rabbit/VirtualMachine.cpp +++ b/rabbit/VirtualMachine.cpp @@ -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_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; diff --git a/rabbit/VirtualMachine.hpp b/rabbit/VirtualMachine.hpp index 98ff432..56111c8 100644 --- a/rabbit/VirtualMachine.hpp +++ b/rabbit/VirtualMachine.hpp @@ -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; diff --git a/rabbit/sqapi.cpp b/rabbit/sqapi.cpp index 96b1ba7..5744f49 100644 --- a/rabbit/sqapi.cpp +++ b/rabbit/sqapi.cpp @@ -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 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); } diff --git a/rabbit/sqbaselib.cpp b/rabbit/sqbaselib.cpp index f2ed8ff..1b5ca2b 100644 --- a/rabbit/sqbaselib.cpp +++ b/rabbit/sqbaselib.cpp @@ -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; } diff --git a/rabbit/sqclosure.hpp b/rabbit/sqclosure.hpp deleted file mode 100644 index a875ed7..0000000 --- a/rabbit/sqclosure.hpp +++ /dev/null @@ -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 -#include - -#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 _stack; - rabbit::VirtualMachine::callInfo _ci; - etk::Vector _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 _typecheck; - rabbit::ObjectPtr *_outervalues; - uint64_t _noutervalues; - rabbit::WeakRef *_env; - SQFUNCTION _function; - rabbit::ObjectPtr _name; -}; - - diff --git a/rabbit/sqcompiler.hpp b/rabbit/sqcompiler.hpp deleted file mode 100644 index 91066ef..0000000 --- a/rabbit/sqcompiler.hpp +++ /dev/null @@ -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); diff --git a/rabbit/sqconfig.hpp b/rabbit/sqconfig.hpp index be1d23d..b735126 100644 --- a/rabbit/sqconfig.hpp +++ b/rabbit/sqconfig.hpp @@ -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; diff --git a/rabbit/sqdebug.cpp b/rabbit/sqdebug.cpp index 36511e1..e6b29ba 100644 --- a/rabbit/sqdebug.cpp +++ b/rabbit/sqdebug.cpp @@ -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) diff --git a/rabbit/sqfuncproto.hpp b/rabbit/sqfuncproto.hpp deleted file mode 100644 index aa5a358..0000000 --- a/rabbit/sqfuncproto.hpp +++ /dev/null @@ -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 - -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 SQOuterVarVec; -typedef etk::Vector SQLocalVarInfoVec; -typedef etk::Vector 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]; -}; diff --git a/rabbit/sqfuncstate.hpp b/rabbit/sqfuncstate.hpp deleted file mode 100644 index d83b28a..0000000 --- a/rabbit/sqfuncstate.hpp +++ /dev/null @@ -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 - -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 _targetstack; - int64_t _stacksize; - bool _varparams; - bool _bgenerator; - etk::Vector _unresolvedbreaks; - etk::Vector _unresolvedcontinues; - etk::Vector _functions; - etk::Vector _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 _scope_blocks; - etk::Vector _breaktargets; - etk::Vector _continuetargets; - etk::Vector _defaultparams; - int64_t _lastline; - int64_t _traps; //contains number of nested exception traps - int64_t _outers; - bool _optimization; - rabbit::SharedState *_sharedstate; - etk::Vector _childstates; - int64_t getConstant(const rabbit::Object &cons); -private: - compilererrorFunc _errfunc; - void *_errtarget; - rabbit::SharedState *_ss; -}; - - diff --git a/rabbit/sqlexer.hpp b/rabbit/sqlexer.hpp deleted file mode 100644 index 34dd46b..0000000 --- a/rabbit/sqlexer.hpp +++ /dev/null @@ -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 _longstr; - compilererrorFunc _errfunc; - void *_errtarget; -}; - diff --git a/rabbit/sqobject.cpp b/rabbit/sqobject.cpp deleted file mode 100644 index 2079065..0000000 --- a/rabbit/sqobject.cpp +++ /dev/null @@ -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 -#include - -#include - -#include -#include - -#include - -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_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_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=nseq){ - for(uint64_t i=0;i=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;isave(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; -} - diff --git a/rabbit/sqobject.hpp b/rabbit/sqobject.hpp deleted file mode 100644 index 21ca789..0000000 --- a/rabbit/sqobject.hpp +++ /dev/null @@ -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 -#include -#include - -#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(); \ - } \ -} diff --git a/rabbit/sqopcodes.hpp b/rabbit/sqopcodes.hpp index 0fa4ace..20bb61c 100644 --- a/rabbit/sqopcodes.hpp +++ b/rabbit/sqopcodes.hpp @@ -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 -typedef etk::Vector SQInstructionVec; +typedef etk::Vector rabbit::InstructionVec; #define NEW_SLOT_ATTRIBUTES_FLAG 0x01 #define NEW_SLOT_STATIC_FLAG 0x02 diff --git a/rabbit/sqpcheader.hpp b/rabbit/sqpcheader.hpp deleted file mode 100644 index 4ab3e6b..0000000 --- a/rabbit/sqpcheader.hpp +++ /dev/null @@ -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 -#endif - -#include -#include -#include -#include -#include -#include -//rabbit stuff -#include -#include - - diff --git a/rabbit/squtils.hpp b/rabbit/squtils.hpp index 2cc880f..e2502ff 100644 --- a/rabbit/squtils.hpp +++ b/rabbit/squtils.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 + +#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(); \ + } \ +}