[STYLE] change ' ' in \t

This commit is contained in:
Edouard DUPIN 2018-06-27 00:50:45 +02:00
parent 92ffade769
commit 7e62732281
45 changed files with 10543 additions and 10543 deletions

View File

@ -36,57 +36,57 @@ void PrintVersionInfos();
#if defined(_MSC_VER) && defined(_DEBUG) #if defined(_MSC_VER) && defined(_DEBUG)
int MemAllocHook(int allocType, int MemAllocHook(int allocType,
void *userData, void *userData,
size_t size, size_t size,
int blockType, int blockType,
long requestNumber, long requestNumber,
const unsigned char *filename, const unsigned char *filename,
int lineNumber) { int lineNumber) {
//if(requestNumber==769)_asm int 3; //if(requestNumber==769)_asm int 3;
return 1; return 1;
} }
#endif #endif
SQInteger quit(HRABBITVM v) SQInteger quit(HRABBITVM v)
{ {
int *done; int *done;
sq_getuserpointer(v,-1,(SQUserPointer*)&done); sq_getuserpointer(v,-1,(SQUserPointer*)&done);
*done=1; *done=1;
return 0; return 0;
} }
void printfunc(HRABBITVM SQ_UNUSED_ARG(v),const SQChar *s,...) void printfunc(HRABBITVM SQ_UNUSED_ARG(v),const SQChar *s,...)
{ {
va_list vl; va_list vl;
va_start(vl, s); va_start(vl, s);
scvprintf(stdout, s, vl); scvprintf(stdout, s, vl);
va_end(vl); va_end(vl);
} }
void errorfunc(HRABBITVM SQ_UNUSED_ARG(v),const SQChar *s,...) void errorfunc(HRABBITVM SQ_UNUSED_ARG(v),const SQChar *s,...)
{ {
va_list vl; va_list vl;
va_start(vl, s); va_start(vl, s);
scvprintf(stderr, s, vl); scvprintf(stderr, s, vl);
va_end(vl); va_end(vl);
} }
void PrintVersionInfos() void PrintVersionInfos()
{ {
scfprintf(stdout,_SC("%s %s (%d bits)\n"),RABBIT_VERSION,RABBIT_COPYRIGHT,((int)(sizeof(SQInteger)*8))); scfprintf(stdout,_SC("%s %s (%d bits)\n"),RABBIT_VERSION,RABBIT_COPYRIGHT,((int)(sizeof(SQInteger)*8)));
} }
void PrintUsage() void PrintUsage()
{ {
scfprintf(stderr,_SC("usage: sq <options> <scriptpath [args]>.\n") scfprintf(stderr,_SC("usage: sq <options> <scriptpath [args]>.\n")
_SC("Available options are:\n") _SC("Available options are:\n")
_SC(" -c compiles the file to bytecode(default output 'out.karrot')\n") _SC(" -c compiles the file to bytecode(default output 'out.karrot')\n")
_SC(" -o specifies output file for the -c option\n") _SC(" -o specifies output file for the -c option\n")
_SC(" -c compiles only\n") _SC(" -c compiles only\n")
_SC(" -d generates debug infos\n") _SC(" -d generates debug infos\n")
_SC(" -v displays version infos\n") _SC(" -v displays version infos\n")
_SC(" -h prints help\n")); _SC(" -h prints help\n"));
} }
#define _INTERACTIVE 0 #define _INTERACTIVE 0
@ -95,265 +95,265 @@ void PrintUsage()
//<<FIXME>> this func is a mess //<<FIXME>> this func is a mess
int getargs(HRABBITVM v,int argc, char* argv[],SQInteger *retval) int getargs(HRABBITVM v,int argc, char* argv[],SQInteger *retval)
{ {
int i; int i;
int compiles_only = 0; int compiles_only = 0;
#ifdef SQUNICODE #ifdef SQUNICODE
static SQChar temp[500]; static SQChar temp[500];
#endif #endif
char * output = NULL; char * output = NULL;
*retval = 0; *retval = 0;
if(argc>1) if(argc>1)
{ {
int arg=1,exitloop=0; int arg=1,exitloop=0;
while(arg < argc && !exitloop) while(arg < argc && !exitloop)
{ {
if(argv[arg][0]=='-') if(argv[arg][0]=='-')
{ {
switch(argv[arg][1]) switch(argv[arg][1])
{ {
case 'd': case 'd':
sq_enabledebuginfo(v,1); sq_enabledebuginfo(v,1);
break; break;
case 'c': case 'c':
compiles_only = 1; compiles_only = 1;
break; break;
case 'o': case 'o':
if(arg < argc) { if(arg < argc) {
arg++; arg++;
output = argv[arg]; output = argv[arg];
} }
break; break;
case 'v': case 'v':
PrintVersionInfos(); PrintVersionInfos();
return _DONE; return _DONE;
case 'h': case 'h':
PrintVersionInfos(); PrintVersionInfos();
PrintUsage(); PrintUsage();
return _DONE; return _DONE;
default: default:
PrintVersionInfos(); PrintVersionInfos();
scprintf(_SC("unknown prameter '-%c'\n"),argv[arg][1]); scprintf(_SC("unknown prameter '-%c'\n"),argv[arg][1]);
PrintUsage(); PrintUsage();
*retval = -1; *retval = -1;
return _ERROR; return _ERROR;
} }
}else break; }else break;
arg++; arg++;
} }
// src file // src file
if(arg<argc) { if(arg<argc) {
const SQChar *filename=NULL; const SQChar *filename=NULL;
#ifdef SQUNICODE #ifdef SQUNICODE
mbstowcs(temp,argv[arg],strlen(argv[arg])); mbstowcs(temp,argv[arg],strlen(argv[arg]));
filename=temp; filename=temp;
#else #else
filename=argv[arg]; filename=argv[arg];
#endif #endif
arg++; arg++;
//sq_pushstring(v,_SC("ARGS"),-1); //sq_pushstring(v,_SC("ARGS"),-1);
//sq_newarray(v,0); //sq_newarray(v,0);
//sq_createslot(v,-3); //sq_createslot(v,-3);
//sq_pop(v,1); //sq_pop(v,1);
if(compiles_only) { if(compiles_only) {
if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,SQTrue))){ if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,SQTrue))){
const SQChar *outfile = _SC("out.karrot"); const SQChar *outfile = _SC("out.karrot");
if(output) { if(output) {
#ifdef SQUNICODE #ifdef SQUNICODE
int len = (int)(strlen(output)+1); int len = (int)(strlen(output)+1);
mbstowcs(sq_getscratchpad(v,len*sizeof(SQChar)),output,len); mbstowcs(sq_getscratchpad(v,len*sizeof(SQChar)),output,len);
outfile = sq_getscratchpad(v,-1); outfile = sq_getscratchpad(v,-1);
#else #else
outfile = output; outfile = output;
#endif #endif
} }
if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,outfile))) if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,outfile)))
return _DONE; return _DONE;
} }
} }
else { else {
//if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQFalse,SQTrue))) { //if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQFalse,SQTrue))) {
//return _DONE; //return _DONE;
//} //}
if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,SQTrue))) { if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,SQTrue))) {
int callargs = 1; int callargs = 1;
sq_pushroottable(v); sq_pushroottable(v);
for(i=arg;i<argc;i++) for(i=arg;i<argc;i++)
{ {
const SQChar *a; const SQChar *a;
#ifdef SQUNICODE #ifdef SQUNICODE
int alen=(int)strlen(argv[i]); int alen=(int)strlen(argv[i]);
a=sq_getscratchpad(v,(int)(alen*sizeof(SQChar))); a=sq_getscratchpad(v,(int)(alen*sizeof(SQChar)));
mbstowcs(sq_getscratchpad(v,-1),argv[i],alen); mbstowcs(sq_getscratchpad(v,-1),argv[i],alen);
sq_getscratchpad(v,-1)[alen] = _SC('\0'); sq_getscratchpad(v,-1)[alen] = _SC('\0');
#else #else
a=argv[i]; a=argv[i];
#endif #endif
sq_pushstring(v,a,-1); sq_pushstring(v,a,-1);
callargs++; callargs++;
//sq_arrayappend(v,-2); //sq_arrayappend(v,-2);
} }
if(SQ_SUCCEEDED(sq_call(v,callargs,SQTrue,SQTrue))) { if(SQ_SUCCEEDED(sq_call(v,callargs,SQTrue,SQTrue))) {
SQObjectType type = sq_gettype(v,-1); SQObjectType type = sq_gettype(v,-1);
if(type == OT_INTEGER) { if(type == OT_INTEGER) {
*retval = type; *retval = type;
sq_getinteger(v,-1,retval); sq_getinteger(v,-1,retval);
} }
return _DONE; return _DONE;
} }
else{ else{
return _ERROR; return _ERROR;
} }
} }
} }
//if this point is reached an error occurred //if this point is reached an error occurred
{ {
const SQChar *err; const SQChar *err;
sq_getlasterror(v); sq_getlasterror(v);
if(SQ_SUCCEEDED(sq_getstring(v,-1,&err))) { if(SQ_SUCCEEDED(sq_getstring(v,-1,&err))) {
scprintf(_SC("Error [%s]\n"),err); scprintf(_SC("Error [%s]\n"),err);
*retval = -2; *retval = -2;
return _ERROR; return _ERROR;
} }
} }
} }
} }
return _INTERACTIVE; return _INTERACTIVE;
} }
void Interactive(HRABBITVM v) void Interactive(HRABBITVM v)
{ {
#define MAXINPUT 1024 #define MAXINPUT 1024
SQChar buffer[MAXINPUT]; SQChar buffer[MAXINPUT];
SQInteger blocks =0; SQInteger blocks =0;
SQInteger string=0; SQInteger string=0;
SQInteger retval=0; SQInteger retval=0;
SQInteger done=0; SQInteger done=0;
PrintVersionInfos(); PrintVersionInfos();
sq_pushroottable(v); sq_pushroottable(v);
sq_pushstring(v,_SC("quit"),-1); sq_pushstring(v,_SC("quit"),-1);
sq_pushuserpointer(v,&done); sq_pushuserpointer(v,&done);
sq_newclosure(v,quit,1); sq_newclosure(v,quit,1);
sq_setparamscheck(v,1,NULL); sq_setparamscheck(v,1,NULL);
sq_newslot(v,-3,SQFalse); sq_newslot(v,-3,SQFalse);
sq_pop(v,1); sq_pop(v,1);
while (!done) while (!done)
{ {
SQInteger i = 0; SQInteger i = 0;
scprintf(_SC("\nrabbit> ")); scprintf(_SC("\nrabbit> "));
for(;;) { for(;;) {
int c; int c;
if(done)return; if(done)return;
c = getchar(); c = getchar();
if (c == _SC('\n')) { if (c == _SC('\n')) {
if (i>0 && buffer[i-1] == _SC('\\')) if (i>0 && buffer[i-1] == _SC('\\'))
{ {
buffer[i-1] = _SC('\n'); buffer[i-1] = _SC('\n');
} }
else if(blocks==0)break; else if(blocks==0)break;
buffer[i++] = _SC('\n'); buffer[i++] = _SC('\n');
} }
else if (c==_SC('}')) {blocks--; buffer[i++] = (SQChar)c;} else if (c==_SC('}')) {blocks--; buffer[i++] = (SQChar)c;}
else if(c==_SC('{') && !string){ else if(c==_SC('{') && !string){
blocks++; blocks++;
buffer[i++] = (SQChar)c; buffer[i++] = (SQChar)c;
} }
else if(c==_SC('"') || c==_SC('\'')){ else if(c==_SC('"') || c==_SC('\'')){
string=!string; string=!string;
buffer[i++] = (SQChar)c; buffer[i++] = (SQChar)c;
} }
else if (i >= MAXINPUT-1) { else if (i >= MAXINPUT-1) {
scfprintf(stderr, _SC("sq : input line too long\n")); scfprintf(stderr, _SC("sq : input line too long\n"));
break; break;
} }
else{ else{
buffer[i++] = (SQChar)c; buffer[i++] = (SQChar)c;
} }
} }
buffer[i] = _SC('\0'); buffer[i] = _SC('\0');
if(buffer[0]==_SC('=')){ if(buffer[0]==_SC('=')){
scsprintf(sq_getscratchpad(v,MAXINPUT),(size_t)MAXINPUT,_SC("return (%s)"),&buffer[1]); scsprintf(sq_getscratchpad(v,MAXINPUT),(size_t)MAXINPUT,_SC("return (%s)"),&buffer[1]);
memcpy(buffer,sq_getscratchpad(v,-1),(scstrlen(sq_getscratchpad(v,-1))+1)*sizeof(SQChar)); memcpy(buffer,sq_getscratchpad(v,-1),(scstrlen(sq_getscratchpad(v,-1))+1)*sizeof(SQChar));
retval=1; retval=1;
} }
i=scstrlen(buffer); i=scstrlen(buffer);
if(i>0){ if(i>0){
SQInteger oldtop=sq_gettop(v); SQInteger oldtop=sq_gettop(v);
if(SQ_SUCCEEDED(sq_compilebuffer(v,buffer,i,_SC("interactive console"),SQTrue))){ if(SQ_SUCCEEDED(sq_compilebuffer(v,buffer,i,_SC("interactive console"),SQTrue))){
sq_pushroottable(v); sq_pushroottable(v);
if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue)) && retval){ if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue)) && retval){
scprintf(_SC("\n")); scprintf(_SC("\n"));
sq_pushroottable(v); sq_pushroottable(v);
sq_pushstring(v,_SC("print"),-1); sq_pushstring(v,_SC("print"),-1);
sq_get(v,-2); sq_get(v,-2);
sq_pushroottable(v); sq_pushroottable(v);
sq_push(v,-4); sq_push(v,-4);
sq_call(v,2,SQFalse,SQTrue); sq_call(v,2,SQFalse,SQTrue);
retval=0; retval=0;
scprintf(_SC("\n")); scprintf(_SC("\n"));
} }
} }
sq_settop(v,oldtop); sq_settop(v,oldtop);
} }
} }
} }
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
HRABBITVM v; HRABBITVM v;
SQInteger retval = 0; SQInteger retval = 0;
#if defined(_MSC_VER) && defined(_DEBUG) #if defined(_MSC_VER) && defined(_DEBUG)
_CrtSetAllocHook(MemAllocHook); _CrtSetAllocHook(MemAllocHook);
#endif #endif
v=sq_open(1024); v=sq_open(1024);
sq_setprintfunc(v,printfunc,errorfunc); sq_setprintfunc(v,printfunc,errorfunc);
sq_pushroottable(v); sq_pushroottable(v);
sqstd_register_bloblib(v); sqstd_register_bloblib(v);
sqstd_register_iolib(v); sqstd_register_iolib(v);
sqstd_register_systemlib(v); sqstd_register_systemlib(v);
sqstd_register_mathlib(v); sqstd_register_mathlib(v);
sqstd_register_stringlib(v); sqstd_register_stringlib(v);
//aux library //aux library
//sets error handlers //sets error handlers
sqstd_seterrorhandlers(v); sqstd_seterrorhandlers(v);
//gets arguments //gets arguments
switch(getargs(v,argc,argv,&retval)) switch(getargs(v,argc,argv,&retval))
{ {
case _INTERACTIVE: case _INTERACTIVE:
Interactive(v); Interactive(v);
break; break;
case _DONE: case _DONE:
case _ERROR: case _ERROR:
default: default:
break; break;
} }
sq_close(v); sq_close(v);
#if defined(_MSC_VER) && defined(_DEBUG) #if defined(_MSC_VER) && defined(_DEBUG)
_getch(); _getch();
_CrtMemDumpAllObjectsSince( NULL ); _CrtMemDumpAllObjectsSince( NULL );
#endif #endif
return retval; return retval;
} }

View File

@ -30,7 +30,7 @@ import time
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones. # ones.
extensions = [ extensions = [
'sphinx.ext.pngmath', 'sphinx.ext.pngmath',
] ]
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
@ -225,10 +225,10 @@ latex_elements = {
# author, documentclass [howto, manual, or own class]). # author, documentclass [howto, manual, or own class]).
_stdauthor = r'Alberto Demichelis' _stdauthor = r'Alberto Demichelis'
latex_documents = [ latex_documents = [
('reference/index', 'reference.tex', ('reference/index', 'reference.tex',
'Squirrel Reference Manual', _stdauthor, 'manual'), 'Squirrel Reference Manual', _stdauthor, 'manual'),
('stdlib/index', 'stdlib.tex', ('stdlib/index', 'stdlib.tex',
'Squirrel Standard Library', _stdauthor, 'manual'), 'Squirrel Standard Library', _stdauthor, 'manual'),
] ]
# The name of an image file (relative to this directory) to place at the top of # The name of an image file (relative to this directory) to place at the top of
@ -257,8 +257,8 @@ latex_documents = [
# One entry per manual page. List of tuples # One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section). # (source start file, name, description, authors, manual section).
man_pages = [ man_pages = [
(master_doc, 'Squirrel', u'Squirrel Documentation', (master_doc, 'Squirrel', u'Squirrel Documentation',
[author], 1) [author], 1)
] ]
# If true, show URL addresses after external links. # If true, show URL addresses after external links.
@ -271,9 +271,9 @@ man_pages = [
# (source start file, target name, title, author, # (source start file, target name, title, author,
# dir menu entry, description, category) # dir menu entry, description, category)
texinfo_documents = [ texinfo_documents = [
(master_doc, 'Squirrel', u'Squirrel Documentation', (master_doc, 'Squirrel', u'Squirrel Documentation',
author, 'Squirrel', 'The Programming Language.', author, 'Squirrel', 'The Programming Language.',
'Miscellaneous'), 'Miscellaneous'),
] ]
# Documents to append as an appendix to all manuals. # Documents to append as an appendix to all manuals.

View File

@ -20,59 +20,59 @@
void printfunc(HSQUIRRELVM v,const SQChar *s,...) void printfunc(HSQUIRRELVM v,const SQChar *s,...)
{ {
va_list vl; va_list vl;
va_start(vl, s); va_start(vl, s);
scvprintf(stdout, s, vl); scvprintf(stdout, s, vl);
va_end(vl); va_end(vl);
} }
void errorfunc(HSQUIRRELVM v,const SQChar *s,...) void errorfunc(HSQUIRRELVM v,const SQChar *s,...)
{ {
va_list vl; va_list vl;
va_start(vl, s); va_start(vl, s);
scvprintf(stderr, s, vl); scvprintf(stderr, s, vl);
va_end(vl); va_end(vl);
} }
void call_foo(HSQUIRRELVM v, int n,float f,const SQChar *s) void call_foo(HSQUIRRELVM v, int n,float f,const SQChar *s)
{ {
SQInteger top = sq_gettop(v); //saves the stack size before the call SQInteger top = sq_gettop(v); //saves the stack size before the call
sq_pushroottable(v); //pushes the global table sq_pushroottable(v); //pushes the global table
sq_pushstring(v,_SC("foo"),-1); sq_pushstring(v,_SC("foo"),-1);
if(SQ_SUCCEEDED(sq_get(v,-2))) { //gets the field 'foo' from the global table if(SQ_SUCCEEDED(sq_get(v,-2))) { //gets the field 'foo' from the global table
sq_pushroottable(v); //push the 'this' (in this case is the global table) sq_pushroottable(v); //push the 'this' (in this case is the global table)
sq_pushinteger(v,n); sq_pushinteger(v,n);
sq_pushfloat(v,f); sq_pushfloat(v,f);
sq_pushstring(v,s,-1); sq_pushstring(v,s,-1);
sq_call(v,4,SQFalse,SQTrue); //calls the function sq_call(v,4,SQFalse,SQTrue); //calls the function
} }
sq_settop(v,top); //restores the original stack size sq_settop(v,top); //restores the original stack size
} }
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
HSQUIRRELVM v; HSQUIRRELVM v;
v = sq_open(1024); // creates a VM with initial stack size 1024 v = sq_open(1024); // creates a VM with initial stack size 1024
//REGISTRATION OF STDLIB //REGISTRATION OF STDLIB
//sq_pushroottable(v); //push the root table where the std function will be registered //sq_pushroottable(v); //push the root table where the std function will be registered
//sqstd_register_iolib(v); //registers a library //sqstd_register_iolib(v); //registers a library
// ... call here other stdlibs string,math etc... // ... call here other stdlibs string,math etc...
//sq_pop(v,1); //pops the root table //sq_pop(v,1); //pops the root table
//END REGISTRATION OF STDLIB //END REGISTRATION OF STDLIB
sqstd_seterrorhandlers(v); //registers the default error handlers sqstd_seterrorhandlers(v); //registers the default error handlers
sq_setprintfunc(v, printfunc,errorfunc); //sets the print function sq_setprintfunc(v, printfunc,errorfunc); //sets the print function
sq_pushroottable(v); //push the root table(were the globals of the script will be stored) sq_pushroottable(v); //push the root table(were the globals of the script will be stored)
if(SQ_SUCCEEDED(sqstd_dofile(v, _SC("test.nut"), SQFalse, SQTrue))) // also prints syntax errors if any if(SQ_SUCCEEDED(sqstd_dofile(v, _SC("test.nut"), SQFalse, SQTrue))) // also prints syntax errors if any
{ {
call_foo(v,1,2.5,_SC("teststring")); call_foo(v,1,2.5,_SC("teststring"));
} }
sq_pop(v,1); //pops the root table sq_pop(v,1); //pops the root table
sq_close(v); sq_close(v);
return 0; return 0;
} }

View File

@ -27,45 +27,45 @@ def get_version():
def configure(target, my_module): def configure(target, my_module):
my_module.add_src_file([ my_module.add_src_file([
'rabbit/sqmem.cpp', 'rabbit/sqmem.cpp',
'rabbit/sqbaselib.cpp', 'rabbit/sqbaselib.cpp',
'rabbit/sqapi.cpp', 'rabbit/sqapi.cpp',
'rabbit/sqlexer.cpp', 'rabbit/sqlexer.cpp',
'rabbit/sqclass.cpp', 'rabbit/sqclass.cpp',
'rabbit/sqvm.cpp', 'rabbit/sqvm.cpp',
'rabbit/sqtable.cpp', 'rabbit/sqtable.cpp',
'rabbit/sqstate.cpp', 'rabbit/sqstate.cpp',
'rabbit/sqobject.cpp', 'rabbit/sqobject.cpp',
'rabbit/sqcompiler.cpp', 'rabbit/sqcompiler.cpp',
'rabbit/sqdebug.cpp', 'rabbit/sqdebug.cpp',
'rabbit/sqfuncstate.cpp', 'rabbit/sqfuncstate.cpp',
]) ])
my_module.compile_version("c++", 2011) my_module.compile_version("c++", 2011)
my_module.add_depend([ my_module.add_depend([
'z', 'z',
'm', 'm',
'c' 'c'
]) ])
my_module.add_header_file([ my_module.add_header_file([
'rabbit/sqclass.hpp', 'rabbit/sqclass.hpp',
'rabbit/sqvm.hpp', 'rabbit/sqvm.hpp',
'rabbit/sqstate.hpp', 'rabbit/sqstate.hpp',
'rabbit/rabbit.hpp', 'rabbit/rabbit.hpp',
'rabbit/sqobject.hpp', 'rabbit/sqobject.hpp',
'rabbit/sqopcodes.hpp', 'rabbit/sqopcodes.hpp',
'rabbit/squserdata.hpp', 'rabbit/squserdata.hpp',
'rabbit/squtils.hpp', 'rabbit/squtils.hpp',
'rabbit/sqpcheader.hpp', 'rabbit/sqpcheader.hpp',
'rabbit/sqfuncproto.hpp', 'rabbit/sqfuncproto.hpp',
'rabbit/sqconfig.hpp', 'rabbit/sqconfig.hpp',
'rabbit/sqcompiler.hpp', 'rabbit/sqcompiler.hpp',
'rabbit/sqarray.hpp', 'rabbit/sqarray.hpp',
'rabbit/sqclosure.hpp', 'rabbit/sqclosure.hpp',
'rabbit/sqlexer.hpp', 'rabbit/sqlexer.hpp',
'rabbit/sqfuncstate.hpp', 'rabbit/sqfuncstate.hpp',
'rabbit/sqstring.hpp', 'rabbit/sqstring.hpp',
'rabbit/sqtable.hpp', 'rabbit/sqtable.hpp',
]) ])
return True return True

View File

@ -27,29 +27,29 @@ def get_version():
def configure(target, my_module): def configure(target, my_module):
my_module.add_src_file([ my_module.add_src_file([
'rabbit-std/sqstdaux.cpp', 'rabbit-std/sqstdaux.cpp',
'rabbit-std/sqstdstream.cpp', 'rabbit-std/sqstdstream.cpp',
'rabbit-std/sqstdrex.cpp', 'rabbit-std/sqstdrex.cpp',
'rabbit-std/sqstdsystem.cpp', 'rabbit-std/sqstdsystem.cpp',
'rabbit-std/sqstdio.cpp', 'rabbit-std/sqstdio.cpp',
'rabbit-std/sqstdblob.cpp', 'rabbit-std/sqstdblob.cpp',
'rabbit-std/sqstdmath.cpp', 'rabbit-std/sqstdmath.cpp',
'rabbit-std/sqstdstring.cpp', 'rabbit-std/sqstdstring.cpp',
]) ])
my_module.compile_version("c++", 2011) my_module.compile_version("c++", 2011)
my_module.add_depend([ my_module.add_depend([
'rabbit-core' 'rabbit-core'
]) ])
my_module.add_header_file([ my_module.add_header_file([
'rabbit-std/sqstdstring.hpp', 'rabbit-std/sqstdstring.hpp',
'rabbit-std/sqstdmath.hpp', 'rabbit-std/sqstdmath.hpp',
'rabbit-std/sqstdaux.hpp', 'rabbit-std/sqstdaux.hpp',
'rabbit-std/sqstdsystem.hpp', 'rabbit-std/sqstdsystem.hpp',
'rabbit-std/sqstdblobimpl.hpp', 'rabbit-std/sqstdblobimpl.hpp',
'rabbit-std/sqstdstream.hpp', 'rabbit-std/sqstdstream.hpp',
'rabbit-std/sqstdio.hpp', 'rabbit-std/sqstdio.hpp',
'rabbit-std/sqstdblob.hpp', 'rabbit-std/sqstdblob.hpp',
]) ])
return True return True

View File

@ -27,14 +27,14 @@ def get_version():
def configure(target, my_module): def configure(target, my_module):
my_module.add_src_file([ my_module.add_src_file([
'cmdLine/rabbit.cpp', 'cmdLine/rabbit.cpp',
]) ])
my_module.compile_version("c++", 2011) my_module.compile_version("c++", 2011)
my_module.add_depend([ my_module.add_depend([
'rabbit-core', 'rabbit-core',
'rabbit-std', 'rabbit-std',
'cxx', 'cxx',
]) ])
return True return True

View File

@ -12,126 +12,126 @@
void sqstd_printcallstack(HRABBITVM v) void sqstd_printcallstack(HRABBITVM v)
{ {
SQPRINTFUNCTION pf = sq_geterrorfunc(v); SQPRINTFUNCTION pf = sq_geterrorfunc(v);
if(pf) { if(pf) {
SQStackInfos si; SQStackInfos si;
SQInteger i; SQInteger i;
SQFloat f; SQFloat f;
const SQChar *s; const SQChar *s;
SQInteger level=1; //1 is to skip this function that is level 0 SQInteger level=1; //1 is to skip this function that is level 0
const SQChar *name=0; const SQChar *name=0;
SQInteger seq=0; SQInteger seq=0;
pf(v,_SC("\nCALLSTACK\n")); pf(v,_SC("\nCALLSTACK\n"));
while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si))) while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))
{ {
const SQChar *fn=_SC("unknown"); const SQChar *fn=_SC("unknown");
const SQChar *src=_SC("unknown"); const SQChar *src=_SC("unknown");
if(si.funcname)fn=si.funcname; if(si.funcname)fn=si.funcname;
if(si.source)src=si.source; if(si.source)src=si.source;
pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line); pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line);
level++; level++;
} }
level=0; level=0;
pf(v,_SC("\nLOCALS\n")); pf(v,_SC("\nLOCALS\n"));
for(level=0;level<10;level++){ for(level=0;level<10;level++){
seq=0; seq=0;
while((name = sq_getlocal(v,level,seq))) while((name = sq_getlocal(v,level,seq)))
{ {
seq++; seq++;
switch(sq_gettype(v,-1)) switch(sq_gettype(v,-1))
{ {
case OT_NULL: case OT_NULL:
pf(v,_SC("[%s] NULL\n"),name); pf(v,_SC("[%s] NULL\n"),name);
break; break;
case OT_INTEGER: case OT_INTEGER:
sq_getinteger(v,-1,&i); sq_getinteger(v,-1,&i);
pf(v,_SC("[%s] %d\n"),name,i); pf(v,_SC("[%s] %d\n"),name,i);
break; break;
case OT_FLOAT: case OT_FLOAT:
sq_getfloat(v,-1,&f); sq_getfloat(v,-1,&f);
pf(v,_SC("[%s] %.14g\n"),name,f); pf(v,_SC("[%s] %.14g\n"),name,f);
break; break;
case OT_USERPOINTER: case OT_USERPOINTER:
pf(v,_SC("[%s] USERPOINTER\n"),name); pf(v,_SC("[%s] USERPOINTER\n"),name);
break; break;
case OT_STRING: case OT_STRING:
sq_getstring(v,-1,&s); sq_getstring(v,-1,&s);
pf(v,_SC("[%s] \"%s\"\n"),name,s); pf(v,_SC("[%s] \"%s\"\n"),name,s);
break; break;
case OT_TABLE: case OT_TABLE:
pf(v,_SC("[%s] TABLE\n"),name); pf(v,_SC("[%s] TABLE\n"),name);
break; break;
case OT_ARRAY: case OT_ARRAY:
pf(v,_SC("[%s] ARRAY\n"),name); pf(v,_SC("[%s] ARRAY\n"),name);
break; break;
case OT_CLOSURE: case OT_CLOSURE:
pf(v,_SC("[%s] CLOSURE\n"),name); pf(v,_SC("[%s] CLOSURE\n"),name);
break; break;
case OT_NATIVECLOSURE: case OT_NATIVECLOSURE:
pf(v,_SC("[%s] NATIVECLOSURE\n"),name); pf(v,_SC("[%s] NATIVECLOSURE\n"),name);
break; break;
case OT_GENERATOR: case OT_GENERATOR:
pf(v,_SC("[%s] GENERATOR\n"),name); pf(v,_SC("[%s] GENERATOR\n"),name);
break; break;
case OT_USERDATA: case OT_USERDATA:
pf(v,_SC("[%s] USERDATA\n"),name); pf(v,_SC("[%s] USERDATA\n"),name);
break; break;
case OT_THREAD: case OT_THREAD:
pf(v,_SC("[%s] THREAD\n"),name); pf(v,_SC("[%s] THREAD\n"),name);
break; break;
case OT_CLASS: case OT_CLASS:
pf(v,_SC("[%s] CLASS\n"),name); pf(v,_SC("[%s] CLASS\n"),name);
break; break;
case OT_INSTANCE: case OT_INSTANCE:
pf(v,_SC("[%s] INSTANCE\n"),name); pf(v,_SC("[%s] INSTANCE\n"),name);
break; break;
case OT_WEAKREF: case OT_WEAKREF:
pf(v,_SC("[%s] WEAKREF\n"),name); pf(v,_SC("[%s] WEAKREF\n"),name);
break; break;
case OT_BOOL:{ case OT_BOOL:{
SQBool bval; SQBool bval;
sq_getbool(v,-1,&bval); sq_getbool(v,-1,&bval);
pf(v,_SC("[%s] %s\n"),name,bval == SQTrue ? _SC("true"):_SC("false")); pf(v,_SC("[%s] %s\n"),name,bval == SQTrue ? _SC("true"):_SC("false"));
} }
break; break;
default: assert(0); break; default: assert(0); break;
} }
sq_pop(v,1); sq_pop(v,1);
} }
} }
} }
} }
static SQInteger _sqstd_aux_printerror(HRABBITVM v) static SQInteger _sqstd_aux_printerror(HRABBITVM v)
{ {
SQPRINTFUNCTION pf = sq_geterrorfunc(v); SQPRINTFUNCTION pf = sq_geterrorfunc(v);
if(pf) { if(pf) {
const SQChar *sErr = 0; const SQChar *sErr = 0;
if(sq_gettop(v)>=1) { if(sq_gettop(v)>=1) {
if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) { if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {
pf(v,_SC("\nAN ERROR HAS OCCURRED [%s]\n"),sErr); pf(v,_SC("\nAN ERROR HAS OCCURRED [%s]\n"),sErr);
} }
else{ else{
pf(v,_SC("\nAN ERROR HAS OCCURRED [unknown]\n")); pf(v,_SC("\nAN ERROR HAS OCCURRED [unknown]\n"));
} }
sqstd_printcallstack(v); sqstd_printcallstack(v);
} }
} }
return 0; return 0;
} }
void _sqstd_compiler_error(HRABBITVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column) void _sqstd_compiler_error(HRABBITVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column)
{ {
SQPRINTFUNCTION pf = sq_geterrorfunc(v); SQPRINTFUNCTION pf = sq_geterrorfunc(v);
if(pf) { if(pf) {
pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr); pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr);
} }
} }
void sqstd_seterrorhandlers(HRABBITVM v) void sqstd_seterrorhandlers(HRABBITVM v)
{ {
sq_setcompilererrorhandler(v,_sqstd_compiler_error); sq_setcompilererrorhandler(v,_sqstd_compiler_error);
sq_newclosure(v,_sqstd_aux_printerror,0); sq_newclosure(v,_sqstd_aux_printerror,0);
sq_seterrorhandler(v); sq_seterrorhandler(v);
} }

View File

@ -13,172 +13,172 @@
#define SETUP_BLOB(v) \ #define SETUP_BLOB(v) \
SQBlob *self = NULL; \ SQBlob *self = NULL; \
{ if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) \ { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) \
return sq_throwerror(v,_SC("invalid type tag")); } \ return sq_throwerror(v,_SC("invalid type tag")); } \
if(!self || !self->IsValid()) \ if(!self || !self->IsValid()) \
return sq_throwerror(v,_SC("the blob is invalid")); return sq_throwerror(v,_SC("the blob is invalid"));
static SQInteger _blob_resize(HRABBITVM v) static SQInteger _blob_resize(HRABBITVM v)
{ {
SETUP_BLOB(v); SETUP_BLOB(v);
SQInteger size; SQInteger size;
sq_getinteger(v,2,&size); sq_getinteger(v,2,&size);
if(!self->Resize(size)) if(!self->Resize(size))
return sq_throwerror(v,_SC("resize failed")); return sq_throwerror(v,_SC("resize failed"));
return 0; return 0;
} }
static void __swap_dword(unsigned int *n) static void __swap_dword(unsigned int *n)
{ {
*n=(unsigned int)(((*n&0xFF000000)>>24) | *n=(unsigned int)(((*n&0xFF000000)>>24) |
((*n&0x00FF0000)>>8) | ((*n&0x00FF0000)>>8) |
((*n&0x0000FF00)<<8) | ((*n&0x0000FF00)<<8) |
((*n&0x000000FF)<<24)); ((*n&0x000000FF)<<24));
} }
static void __swap_word(unsigned short *n) static void __swap_word(unsigned short *n)
{ {
*n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00); *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00);
} }
static SQInteger _blob_swap4(HRABBITVM v) static SQInteger _blob_swap4(HRABBITVM v)
{ {
SETUP_BLOB(v); SETUP_BLOB(v);
SQInteger num=(self->Len()-(self->Len()%4))>>2; SQInteger num=(self->Len()-(self->Len()%4))>>2;
unsigned int *t=(unsigned int *)self->GetBuf(); unsigned int *t=(unsigned int *)self->GetBuf();
for(SQInteger i = 0; i < num; i++) { for(SQInteger i = 0; i < num; i++) {
__swap_dword(&t[i]); __swap_dword(&t[i]);
} }
return 0; return 0;
} }
static SQInteger _blob_swap2(HRABBITVM v) static SQInteger _blob_swap2(HRABBITVM v)
{ {
SETUP_BLOB(v); SETUP_BLOB(v);
SQInteger num=(self->Len()-(self->Len()%2))>>1; SQInteger num=(self->Len()-(self->Len()%2))>>1;
unsigned short *t = (unsigned short *)self->GetBuf(); unsigned short *t = (unsigned short *)self->GetBuf();
for(SQInteger i = 0; i < num; i++) { for(SQInteger i = 0; i < num; i++) {
__swap_word(&t[i]); __swap_word(&t[i]);
} }
return 0; return 0;
} }
static SQInteger _blob__set(HRABBITVM v) static SQInteger _blob__set(HRABBITVM v)
{ {
SETUP_BLOB(v); SETUP_BLOB(v);
SQInteger idx,val; SQInteger idx,val;
sq_getinteger(v,2,&idx); sq_getinteger(v,2,&idx);
sq_getinteger(v,3,&val); sq_getinteger(v,3,&val);
if(idx < 0 || idx >= self->Len()) if(idx < 0 || idx >= self->Len())
return sq_throwerror(v,_SC("index out of range")); return sq_throwerror(v,_SC("index out of range"));
((unsigned char *)self->GetBuf())[idx] = (unsigned char) val; ((unsigned char *)self->GetBuf())[idx] = (unsigned char) val;
sq_push(v,3); sq_push(v,3);
return 1; return 1;
} }
static SQInteger _blob__get(HRABBITVM v) static SQInteger _blob__get(HRABBITVM v)
{ {
SETUP_BLOB(v); SETUP_BLOB(v);
SQInteger idx; SQInteger idx;
if ((sq_gettype(v, 2) & SQOBJECT_NUMERIC) == 0) if ((sq_gettype(v, 2) & SQOBJECT_NUMERIC) == 0)
{ {
sq_pushnull(v); sq_pushnull(v);
return sq_throwobject(v); return sq_throwobject(v);
} }
sq_getinteger(v,2,&idx); sq_getinteger(v,2,&idx);
if(idx < 0 || idx >= self->Len()) if(idx < 0 || idx >= self->Len())
return sq_throwerror(v,_SC("index out of range")); return sq_throwerror(v,_SC("index out of range"));
sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]); sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]);
return 1; return 1;
} }
static SQInteger _blob__nexti(HRABBITVM v) static SQInteger _blob__nexti(HRABBITVM v)
{ {
SETUP_BLOB(v); SETUP_BLOB(v);
if(sq_gettype(v,2) == OT_NULL) { if(sq_gettype(v,2) == OT_NULL) {
sq_pushinteger(v, 0); sq_pushinteger(v, 0);
return 1; return 1;
} }
SQInteger idx; SQInteger idx;
if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) { if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) {
if(idx+1 < self->Len()) { if(idx+1 < self->Len()) {
sq_pushinteger(v, idx+1); sq_pushinteger(v, idx+1);
return 1; return 1;
} }
sq_pushnull(v); sq_pushnull(v);
return 1; return 1;
} }
return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type")); return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type"));
} }
static SQInteger _blob__typeof(HRABBITVM v) static SQInteger _blob__typeof(HRABBITVM v)
{ {
sq_pushstring(v,_SC("blob"),-1); sq_pushstring(v,_SC("blob"),-1);
return 1; return 1;
} }
static SQInteger _blob_releasehook(SQUserPointer p, SQInteger SQ_UNUSED_ARG(size)) static SQInteger _blob_releasehook(SQUserPointer p, SQInteger SQ_UNUSED_ARG(size))
{ {
SQBlob *self = (SQBlob*)p; SQBlob *self = (SQBlob*)p;
self->~SQBlob(); self->~SQBlob();
sq_free(self,sizeof(SQBlob)); sq_free(self,sizeof(SQBlob));
return 1; return 1;
} }
static SQInteger _blob_constructor(HRABBITVM v) static SQInteger _blob_constructor(HRABBITVM v)
{ {
SQInteger nparam = sq_gettop(v); SQInteger nparam = sq_gettop(v);
SQInteger size = 0; SQInteger size = 0;
if(nparam == 2) { if(nparam == 2) {
sq_getinteger(v, 2, &size); sq_getinteger(v, 2, &size);
} }
if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size")); if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size"));
//SQBlob *b = new SQBlob(size); //SQBlob *b = new SQBlob(size);
SQBlob *b = new (sq_malloc(sizeof(SQBlob)))SQBlob(size); SQBlob *b = new (sq_malloc(sizeof(SQBlob)))SQBlob(size);
if(SQ_FAILED(sq_setinstanceup(v,1,b))) { if(SQ_FAILED(sq_setinstanceup(v,1,b))) {
b->~SQBlob(); b->~SQBlob();
sq_free(b,sizeof(SQBlob)); sq_free(b,sizeof(SQBlob));
return sq_throwerror(v, _SC("cannot create blob")); return sq_throwerror(v, _SC("cannot create blob"));
} }
sq_setreleasehook(v,1,_blob_releasehook); sq_setreleasehook(v,1,_blob_releasehook);
return 0; return 0;
} }
static SQInteger _blob__cloned(HRABBITVM v) static SQInteger _blob__cloned(HRABBITVM v)
{ {
SQBlob *other = NULL; SQBlob *other = NULL;
{ {
if(SQ_FAILED(sq_getinstanceup(v,2,(SQUserPointer*)&other,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) if(SQ_FAILED(sq_getinstanceup(v,2,(SQUserPointer*)&other,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
return SQ_ERROR; return SQ_ERROR;
} }
//SQBlob *thisone = new SQBlob(other->Len()); //SQBlob *thisone = new SQBlob(other->Len());
SQBlob *thisone = new (sq_malloc(sizeof(SQBlob)))SQBlob(other->Len()); SQBlob *thisone = new (sq_malloc(sizeof(SQBlob)))SQBlob(other->Len());
memcpy(thisone->GetBuf(),other->GetBuf(),thisone->Len()); memcpy(thisone->GetBuf(),other->GetBuf(),thisone->Len());
if(SQ_FAILED(sq_setinstanceup(v,1,thisone))) { if(SQ_FAILED(sq_setinstanceup(v,1,thisone))) {
thisone->~SQBlob(); thisone->~SQBlob();
sq_free(thisone,sizeof(SQBlob)); sq_free(thisone,sizeof(SQBlob));
return sq_throwerror(v, _SC("cannot clone blob")); return sq_throwerror(v, _SC("cannot clone blob"));
} }
sq_setreleasehook(v,1,_blob_releasehook); sq_setreleasehook(v,1,_blob_releasehook);
return 0; return 0;
} }
#define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck} #define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck}
static const SQRegFunction _blob_methods[] = { static const SQRegFunction _blob_methods[] = {
_DECL_BLOB_FUNC(constructor,-1,_SC("xn")), _DECL_BLOB_FUNC(constructor,-1,_SC("xn")),
_DECL_BLOB_FUNC(resize,2,_SC("xn")), _DECL_BLOB_FUNC(resize,2,_SC("xn")),
_DECL_BLOB_FUNC(swap2,1,_SC("x")), _DECL_BLOB_FUNC(swap2,1,_SC("x")),
_DECL_BLOB_FUNC(swap4,1,_SC("x")), _DECL_BLOB_FUNC(swap4,1,_SC("x")),
_DECL_BLOB_FUNC(_set,3,_SC("xnn")), _DECL_BLOB_FUNC(_set,3,_SC("xnn")),
_DECL_BLOB_FUNC(_get,2,_SC("x.")), _DECL_BLOB_FUNC(_get,2,_SC("x.")),
_DECL_BLOB_FUNC(_typeof,1,_SC("x")), _DECL_BLOB_FUNC(_typeof,1,_SC("x")),
_DECL_BLOB_FUNC(_nexti,2,_SC("x")), _DECL_BLOB_FUNC(_nexti,2,_SC("x")),
_DECL_BLOB_FUNC(_cloned,2,_SC("xx")), _DECL_BLOB_FUNC(_cloned,2,_SC("xx")),
{NULL,(SQFUNCTION)0,0,NULL} {NULL,(SQFUNCTION)0,0,NULL}
}; };
@ -187,97 +187,97 @@ static const SQRegFunction _blob_methods[] = {
static SQInteger _g_blob_casti2f(HRABBITVM v) static SQInteger _g_blob_casti2f(HRABBITVM v)
{ {
SQInteger i; SQInteger i;
sq_getinteger(v,2,&i); sq_getinteger(v,2,&i);
sq_pushfloat(v,*((const SQFloat *)&i)); sq_pushfloat(v,*((const SQFloat *)&i));
return 1; return 1;
} }
static SQInteger _g_blob_castf2i(HRABBITVM v) static SQInteger _g_blob_castf2i(HRABBITVM v)
{ {
SQFloat f; SQFloat f;
sq_getfloat(v,2,&f); sq_getfloat(v,2,&f);
sq_pushinteger(v,*((const SQInteger *)&f)); sq_pushinteger(v,*((const SQInteger *)&f));
return 1; return 1;
} }
static SQInteger _g_blob_swap2(HRABBITVM v) static SQInteger _g_blob_swap2(HRABBITVM v)
{ {
SQInteger i; SQInteger i;
sq_getinteger(v,2,&i); sq_getinteger(v,2,&i);
short s=(short)i; short s=(short)i;
sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF)); sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF));
return 1; return 1;
} }
static SQInteger _g_blob_swap4(HRABBITVM v) static SQInteger _g_blob_swap4(HRABBITVM v)
{ {
SQInteger i; SQInteger i;
sq_getinteger(v,2,&i); sq_getinteger(v,2,&i);
unsigned int t4 = (unsigned int)i; unsigned int t4 = (unsigned int)i;
__swap_dword(&t4); __swap_dword(&t4);
sq_pushinteger(v,(SQInteger)t4); sq_pushinteger(v,(SQInteger)t4);
return 1; return 1;
} }
static SQInteger _g_blob_swapfloat(HRABBITVM v) static SQInteger _g_blob_swapfloat(HRABBITVM v)
{ {
SQFloat f; SQFloat f;
sq_getfloat(v,2,&f); sq_getfloat(v,2,&f);
__swap_dword((unsigned int *)&f); __swap_dword((unsigned int *)&f);
sq_pushfloat(v,f); sq_pushfloat(v,f);
return 1; return 1;
} }
#define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck} #define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck}
static const SQRegFunction bloblib_funcs[]={ static const SQRegFunction bloblib_funcs[]={
_DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")), _DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")),
_DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")), _DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")),
_DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")), _DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")),
_DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")), _DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")),
_DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")), _DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")),
{NULL,(SQFUNCTION)0,0,NULL} {NULL,(SQFUNCTION)0,0,NULL}
}; };
SQRESULT sqstd_getblob(HRABBITVM v,SQInteger idx,SQUserPointer *ptr) SQRESULT sqstd_getblob(HRABBITVM v,SQInteger idx,SQUserPointer *ptr)
{ {
SQBlob *blob; SQBlob *blob;
if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
return -1; return -1;
*ptr = blob->GetBuf(); *ptr = blob->GetBuf();
return SQ_OK; return SQ_OK;
} }
SQInteger sqstd_getblobsize(HRABBITVM v,SQInteger idx) SQInteger sqstd_getblobsize(HRABBITVM v,SQInteger idx)
{ {
SQBlob *blob; SQBlob *blob;
if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
return -1; return -1;
return blob->Len(); return blob->Len();
} }
SQUserPointer sqstd_createblob(HRABBITVM v, SQInteger size) SQUserPointer sqstd_createblob(HRABBITVM v, SQInteger size)
{ {
SQInteger top = sq_gettop(v); SQInteger top = sq_gettop(v);
sq_pushregistrytable(v); sq_pushregistrytable(v);
sq_pushstring(v,_SC("std_blob"),-1); sq_pushstring(v,_SC("std_blob"),-1);
if(SQ_SUCCEEDED(sq_get(v,-2))) { if(SQ_SUCCEEDED(sq_get(v,-2))) {
sq_remove(v,-2); //removes the registry sq_remove(v,-2); //removes the registry
sq_push(v,1); // push the this sq_push(v,1); // push the this
sq_pushinteger(v,size); //size sq_pushinteger(v,size); //size
SQBlob *blob = NULL; SQBlob *blob = NULL;
if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse)) if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse))
&& SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) { && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) {
sq_remove(v,-2); sq_remove(v,-2);
return blob->GetBuf(); return blob->GetBuf();
} }
} }
sq_settop(v,top); sq_settop(v,top);
return NULL; return NULL;
} }
SQRESULT sqstd_register_bloblib(HRABBITVM v) SQRESULT sqstd_register_bloblib(HRABBITVM v)
{ {
return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs); return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs);
} }

View File

@ -9,104 +9,104 @@
struct SQBlob : public SQStream struct SQBlob : public SQStream
{ {
SQBlob(SQInteger size) { SQBlob(SQInteger size) {
_size = size; _size = size;
_allocated = size; _allocated = size;
_buf = (unsigned char *)sq_malloc(size); _buf = (unsigned char *)sq_malloc(size);
memset(_buf, 0, _size); memset(_buf, 0, _size);
_ptr = 0; _ptr = 0;
_owns = true; _owns = true;
} }
virtual ~SQBlob() { virtual ~SQBlob() {
sq_free(_buf, _allocated); sq_free(_buf, _allocated);
} }
SQInteger Write(void *buffer, SQInteger size) { SQInteger Write(void *buffer, SQInteger size) {
if(!CanAdvance(size)) { if(!CanAdvance(size)) {
GrowBufOf(_ptr + size - _size); GrowBufOf(_ptr + size - _size);
} }
memcpy(&_buf[_ptr], buffer, size); memcpy(&_buf[_ptr], buffer, size);
_ptr += size; _ptr += size;
return size; return size;
} }
SQInteger Read(void *buffer,SQInteger size) { SQInteger Read(void *buffer,SQInteger size) {
SQInteger n = size; SQInteger n = size;
if(!CanAdvance(size)) { if(!CanAdvance(size)) {
if((_size - _ptr) > 0) if((_size - _ptr) > 0)
n = _size - _ptr; n = _size - _ptr;
else return 0; else return 0;
} }
memcpy(buffer, &_buf[_ptr], n); memcpy(buffer, &_buf[_ptr], n);
_ptr += n; _ptr += n;
return n; return n;
} }
bool Resize(SQInteger n) { bool Resize(SQInteger n) {
if(!_owns) return false; if(!_owns) return false;
if(n != _allocated) { if(n != _allocated) {
unsigned char *newbuf = (unsigned char *)sq_malloc(n); unsigned char *newbuf = (unsigned char *)sq_malloc(n);
memset(newbuf,0,n); memset(newbuf,0,n);
if(_size > n) if(_size > n)
memcpy(newbuf,_buf,n); memcpy(newbuf,_buf,n);
else else
memcpy(newbuf,_buf,_size); memcpy(newbuf,_buf,_size);
sq_free(_buf,_allocated); sq_free(_buf,_allocated);
_buf=newbuf; _buf=newbuf;
_allocated = n; _allocated = n;
if(_size > _allocated) if(_size > _allocated)
_size = _allocated; _size = _allocated;
if(_ptr > _allocated) if(_ptr > _allocated)
_ptr = _allocated; _ptr = _allocated;
} }
return true; return true;
} }
bool GrowBufOf(SQInteger n) bool GrowBufOf(SQInteger n)
{ {
bool ret = true; bool ret = true;
if(_size + n > _allocated) { if(_size + n > _allocated) {
if(_size + n > _size * 2) if(_size + n > _size * 2)
ret = Resize(_size + n); ret = Resize(_size + n);
else else
ret = Resize(_size * 2); ret = Resize(_size * 2);
} }
_size = _size + n; _size = _size + n;
return ret; return ret;
} }
bool CanAdvance(SQInteger n) { bool CanAdvance(SQInteger n) {
if(_ptr+n>_size)return false; if(_ptr+n>_size)return false;
return true; return true;
} }
SQInteger Seek(SQInteger offset, SQInteger origin) { SQInteger Seek(SQInteger offset, SQInteger origin) {
switch(origin) { switch(origin) {
case SQ_SEEK_SET: case SQ_SEEK_SET:
if(offset > _size || offset < 0) return -1; if(offset > _size || offset < 0) return -1;
_ptr = offset; _ptr = offset;
break; break;
case SQ_SEEK_CUR: case SQ_SEEK_CUR:
if(_ptr + offset > _size || _ptr + offset < 0) return -1; if(_ptr + offset > _size || _ptr + offset < 0) return -1;
_ptr += offset; _ptr += offset;
break; break;
case SQ_SEEK_END: case SQ_SEEK_END:
if(_size + offset > _size || _size + offset < 0) return -1; if(_size + offset > _size || _size + offset < 0) return -1;
_ptr = _size + offset; _ptr = _size + offset;
break; break;
default: return -1; default: return -1;
} }
return 0; return 0;
} }
bool IsValid() { bool IsValid() {
return _size == 0 || _buf?true:false; return _size == 0 || _buf?true:false;
} }
bool EOS() { bool EOS() {
return _ptr == _size; return _ptr == _size;
} }
SQInteger Flush() { return 0; } SQInteger Flush() { return 0; }
SQInteger Tell() { return _ptr; } SQInteger Tell() { return _ptr; }
SQInteger Len() { return _size; } SQInteger Len() { return _size; }
SQUserPointer GetBuf(){ return _buf; } SQUserPointer GetBuf(){ return _buf; }
private: private:
SQInteger _size; SQInteger _size;
SQInteger _allocated; SQInteger _allocated;
SQInteger _ptr; SQInteger _ptr;
unsigned char *_buf; unsigned char *_buf;
bool _owns; bool _owns;
}; };

View File

@ -17,480 +17,480 @@
SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode) SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode)
{ {
#ifndef SQUNICODE #ifndef SQUNICODE
return (SQFILE)fopen(filename,mode); return (SQFILE)fopen(filename,mode);
#else #else
return (SQFILE)_wfopen(filename,mode); return (SQFILE)_wfopen(filename,mode);
#endif #endif
} }
SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file) SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file)
{ {
SQInteger ret = (SQInteger)fread(buffer,size,count,(FILE *)file); SQInteger ret = (SQInteger)fread(buffer,size,count,(FILE *)file);
return ret; return ret;
} }
SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file) SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file)
{ {
return (SQInteger)fwrite(buffer,size,count,(FILE *)file); return (SQInteger)fwrite(buffer,size,count,(FILE *)file);
} }
SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin) SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin)
{ {
SQInteger realorigin; SQInteger realorigin;
switch(origin) { switch(origin) {
case SQ_SEEK_CUR: realorigin = SEEK_CUR; break; case SQ_SEEK_CUR: realorigin = SEEK_CUR; break;
case SQ_SEEK_END: realorigin = SEEK_END; break; case SQ_SEEK_END: realorigin = SEEK_END; break;
case SQ_SEEK_SET: realorigin = SEEK_SET; break; case SQ_SEEK_SET: realorigin = SEEK_SET; break;
default: return -1; //failed default: return -1; //failed
} }
return fseek((FILE *)file,(long)offset,(int)realorigin); return fseek((FILE *)file,(long)offset,(int)realorigin);
} }
SQInteger sqstd_ftell(SQFILE file) SQInteger sqstd_ftell(SQFILE file)
{ {
return ftell((FILE *)file); return ftell((FILE *)file);
} }
SQInteger sqstd_fflush(SQFILE file) SQInteger sqstd_fflush(SQFILE file)
{ {
return fflush((FILE *)file); return fflush((FILE *)file);
} }
SQInteger sqstd_fclose(SQFILE file) SQInteger sqstd_fclose(SQFILE file)
{ {
return fclose((FILE *)file); return fclose((FILE *)file);
} }
SQInteger sqstd_feof(SQFILE file) SQInteger sqstd_feof(SQFILE file)
{ {
return feof((FILE *)file); return feof((FILE *)file);
} }
//File //File
struct SQFile : public SQStream { struct SQFile : public SQStream {
SQFile() { _handle = NULL; _owns = false;} SQFile() { _handle = NULL; _owns = false;}
SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;} SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;}
virtual ~SQFile() { Close(); } virtual ~SQFile() { Close(); }
bool Open(const SQChar *filename ,const SQChar *mode) { bool Open(const SQChar *filename ,const SQChar *mode) {
Close(); Close();
if( (_handle = sqstd_fopen(filename,mode)) ) { if( (_handle = sqstd_fopen(filename,mode)) ) {
_owns = true; _owns = true;
return true; return true;
} }
return false; return false;
} }
void Close() { void Close() {
if(_handle && _owns) { if(_handle && _owns) {
sqstd_fclose(_handle); sqstd_fclose(_handle);
_handle = NULL; _handle = NULL;
_owns = false; _owns = false;
} }
} }
SQInteger Read(void *buffer,SQInteger size) { SQInteger Read(void *buffer,SQInteger size) {
return sqstd_fread(buffer,1,size,_handle); return sqstd_fread(buffer,1,size,_handle);
} }
SQInteger Write(void *buffer,SQInteger size) { SQInteger Write(void *buffer,SQInteger size) {
return sqstd_fwrite(buffer,1,size,_handle); return sqstd_fwrite(buffer,1,size,_handle);
} }
SQInteger Flush() { SQInteger Flush() {
return sqstd_fflush(_handle); return sqstd_fflush(_handle);
} }
SQInteger Tell() { SQInteger Tell() {
return sqstd_ftell(_handle); return sqstd_ftell(_handle);
} }
SQInteger Len() { SQInteger Len() {
SQInteger prevpos=Tell(); SQInteger prevpos=Tell();
Seek(0,SQ_SEEK_END); Seek(0,SQ_SEEK_END);
SQInteger size=Tell(); SQInteger size=Tell();
Seek(prevpos,SQ_SEEK_SET); Seek(prevpos,SQ_SEEK_SET);
return size; return size;
} }
SQInteger Seek(SQInteger offset, SQInteger origin) { SQInteger Seek(SQInteger offset, SQInteger origin) {
return sqstd_fseek(_handle,offset,origin); return sqstd_fseek(_handle,offset,origin);
} }
bool IsValid() { return _handle?true:false; } bool IsValid() { return _handle?true:false; }
bool EOS() { return Tell()==Len()?true:false;} bool EOS() { return Tell()==Len()?true:false;}
SQFILE GetHandle() {return _handle;} SQFILE GetHandle() {return _handle;}
private: private:
SQFILE _handle; SQFILE _handle;
bool _owns; bool _owns;
}; };
static SQInteger _file__typeof(HRABBITVM v) static SQInteger _file__typeof(HRABBITVM v)
{ {
sq_pushstring(v,_SC("file"),-1); sq_pushstring(v,_SC("file"),-1);
return 1; return 1;
} }
static SQInteger _file_releasehook(SQUserPointer p, SQInteger SQ_UNUSED_ARG(size)) static SQInteger _file_releasehook(SQUserPointer p, SQInteger SQ_UNUSED_ARG(size))
{ {
SQFile *self = (SQFile*)p; SQFile *self = (SQFile*)p;
self->~SQFile(); self->~SQFile();
sq_free(self,sizeof(SQFile)); sq_free(self,sizeof(SQFile));
return 1; return 1;
} }
static SQInteger _file_constructor(HRABBITVM v) static SQInteger _file_constructor(HRABBITVM v)
{ {
const SQChar *filename,*mode; const SQChar *filename,*mode;
bool owns = true; bool owns = true;
SQFile *f; SQFile *f;
SQFILE newf; SQFILE newf;
if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) { if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) {
sq_getstring(v, 2, &filename); sq_getstring(v, 2, &filename);
sq_getstring(v, 3, &mode); sq_getstring(v, 3, &mode);
newf = sqstd_fopen(filename, mode); newf = sqstd_fopen(filename, mode);
if(!newf) return sq_throwerror(v, _SC("cannot open file")); if(!newf) return sq_throwerror(v, _SC("cannot open file"));
} else if(sq_gettype(v,2) == OT_USERPOINTER) { } else if(sq_gettype(v,2) == OT_USERPOINTER) {
owns = !(sq_gettype(v,3) == OT_NULL); owns = !(sq_gettype(v,3) == OT_NULL);
sq_getuserpointer(v,2,&newf); sq_getuserpointer(v,2,&newf);
} else { } else {
return sq_throwerror(v,_SC("wrong parameter")); return sq_throwerror(v,_SC("wrong parameter"));
} }
f = new (sq_malloc(sizeof(SQFile)))SQFile(newf,owns); f = new (sq_malloc(sizeof(SQFile)))SQFile(newf,owns);
if(SQ_FAILED(sq_setinstanceup(v,1,f))) { if(SQ_FAILED(sq_setinstanceup(v,1,f))) {
f->~SQFile(); f->~SQFile();
sq_free(f,sizeof(SQFile)); sq_free(f,sizeof(SQFile));
return sq_throwerror(v, _SC("cannot create blob with negative size")); return sq_throwerror(v, _SC("cannot create blob with negative size"));
} }
sq_setreleasehook(v,1,_file_releasehook); sq_setreleasehook(v,1,_file_releasehook);
return 0; return 0;
} }
static SQInteger _file_close(HRABBITVM v) static SQInteger _file_close(HRABBITVM v)
{ {
SQFile *self = NULL; SQFile *self = NULL;
if(SQ_SUCCEEDED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_FILE_TYPE_TAG)) if(SQ_SUCCEEDED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_FILE_TYPE_TAG))
&& self != NULL) && self != NULL)
{ {
self->Close(); self->Close();
} }
return 0; return 0;
} }
//bindings //bindings
#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck} #define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck}
static const SQRegFunction _file_methods[] = { static const SQRegFunction _file_methods[] = {
_DECL_FILE_FUNC(constructor,3,_SC("x")), _DECL_FILE_FUNC(constructor,3,_SC("x")),
_DECL_FILE_FUNC(_typeof,1,_SC("x")), _DECL_FILE_FUNC(_typeof,1,_SC("x")),
_DECL_FILE_FUNC(close,1,_SC("x")), _DECL_FILE_FUNC(close,1,_SC("x")),
{NULL,(SQFUNCTION)0,0,NULL} {NULL,(SQFUNCTION)0,0,NULL}
}; };
SQRESULT sqstd_createfile(HRABBITVM v, SQFILE file,SQBool own) SQRESULT sqstd_createfile(HRABBITVM v, SQFILE file,SQBool own)
{ {
SQInteger top = sq_gettop(v); SQInteger top = sq_gettop(v);
sq_pushregistrytable(v); sq_pushregistrytable(v);
sq_pushstring(v,_SC("std_file"),-1); sq_pushstring(v,_SC("std_file"),-1);
if(SQ_SUCCEEDED(sq_get(v,-2))) { if(SQ_SUCCEEDED(sq_get(v,-2))) {
sq_remove(v,-2); //removes the registry sq_remove(v,-2); //removes the registry
sq_pushroottable(v); // push the this sq_pushroottable(v); // push the this
sq_pushuserpointer(v,file); //file sq_pushuserpointer(v,file); //file
if(own){ if(own){
sq_pushinteger(v,1); //true sq_pushinteger(v,1); //true
} }
else{ else{
sq_pushnull(v); //false sq_pushnull(v); //false
} }
if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) { if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) {
sq_remove(v,-2); sq_remove(v,-2);
return SQ_OK; return SQ_OK;
} }
} }
sq_settop(v,top); sq_settop(v,top);
return SQ_ERROR; return SQ_ERROR;
} }
SQRESULT sqstd_getfile(HRABBITVM v, SQInteger idx, SQFILE *file) SQRESULT sqstd_getfile(HRABBITVM v, SQInteger idx, SQFILE *file)
{ {
SQFile *fileobj = NULL; SQFile *fileobj = NULL;
if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) { if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) {
*file = fileobj->GetHandle(); *file = fileobj->GetHandle();
return SQ_OK; return SQ_OK;
} }
return sq_throwerror(v,_SC("not a file")); return sq_throwerror(v,_SC("not a file"));
} }
#define IO_BUFFER_SIZE 2048 #define IO_BUFFER_SIZE 2048
struct IOBuffer { struct IOBuffer {
unsigned char buffer[IO_BUFFER_SIZE]; unsigned char buffer[IO_BUFFER_SIZE];
SQInteger size; SQInteger size;
SQInteger ptr; SQInteger ptr;
SQFILE file; SQFILE file;
}; };
SQInteger _read_byte(IOBuffer *iobuffer) SQInteger _read_byte(IOBuffer *iobuffer)
{ {
if(iobuffer->ptr < iobuffer->size) { if(iobuffer->ptr < iobuffer->size) {
SQInteger ret = iobuffer->buffer[iobuffer->ptr]; SQInteger ret = iobuffer->buffer[iobuffer->ptr];
iobuffer->ptr++; iobuffer->ptr++;
return ret; return ret;
} }
else { else {
if( (iobuffer->size = sqstd_fread(iobuffer->buffer,1,IO_BUFFER_SIZE,iobuffer->file )) > 0 ) if( (iobuffer->size = sqstd_fread(iobuffer->buffer,1,IO_BUFFER_SIZE,iobuffer->file )) > 0 )
{ {
SQInteger ret = iobuffer->buffer[0]; SQInteger ret = iobuffer->buffer[0];
iobuffer->ptr = 1; iobuffer->ptr = 1;
return ret; return ret;
} }
} }
return 0; return 0;
} }
SQInteger _read_two_bytes(IOBuffer *iobuffer) SQInteger _read_two_bytes(IOBuffer *iobuffer)
{ {
if(iobuffer->ptr < iobuffer->size) { if(iobuffer->ptr < iobuffer->size) {
if(iobuffer->size < 2) return 0; if(iobuffer->size < 2) return 0;
SQInteger ret = *((const wchar_t*)&iobuffer->buffer[iobuffer->ptr]); SQInteger ret = *((const wchar_t*)&iobuffer->buffer[iobuffer->ptr]);
iobuffer->ptr += 2; iobuffer->ptr += 2;
return ret; return ret;
} }
else { else {
if( (iobuffer->size = sqstd_fread(iobuffer->buffer,1,IO_BUFFER_SIZE,iobuffer->file )) > 0 ) if( (iobuffer->size = sqstd_fread(iobuffer->buffer,1,IO_BUFFER_SIZE,iobuffer->file )) > 0 )
{ {
if(iobuffer->size < 2) return 0; if(iobuffer->size < 2) return 0;
SQInteger ret = *((const wchar_t*)&iobuffer->buffer[0]); SQInteger ret = *((const wchar_t*)&iobuffer->buffer[0]);
iobuffer->ptr = 2; iobuffer->ptr = 2;
return ret; return ret;
} }
} }
return 0; return 0;
} }
static SQInteger _io_file_lexfeed_PLAIN(SQUserPointer iobuf) static SQInteger _io_file_lexfeed_PLAIN(SQUserPointer iobuf)
{ {
IOBuffer *iobuffer = (IOBuffer *)iobuf; IOBuffer *iobuffer = (IOBuffer *)iobuf;
return _read_byte(iobuffer); return _read_byte(iobuffer);
} }
#ifdef SQUNICODE #ifdef SQUNICODE
static SQInteger _io_file_lexfeed_UTF8(SQUserPointer iobuf) static SQInteger _io_file_lexfeed_UTF8(SQUserPointer iobuf)
{ {
IOBuffer *iobuffer = (IOBuffer *)iobuf; IOBuffer *iobuffer = (IOBuffer *)iobuf;
#define READ(iobuf) \ #define READ(iobuf) \
if((inchar = (unsigned char)_read_byte(iobuf)) == 0) \ if((inchar = (unsigned char)_read_byte(iobuf)) == 0) \
return 0; return 0;
static const SQInteger utf8_lengths[16] = static const SQInteger utf8_lengths[16] =
{ {
1,1,1,1,1,1,1,1, /* 0000 to 0111 : 1 byte (plain ASCII) */ 1,1,1,1,1,1,1,1, /* 0000 to 0111 : 1 byte (plain ASCII) */
0,0,0,0, /* 1000 to 1011 : not valid */ 0,0,0,0, /* 1000 to 1011 : not valid */
2,2, /* 1100, 1101 : 2 bytes */ 2,2, /* 1100, 1101 : 2 bytes */
3, /* 1110 : 3 bytes */ 3, /* 1110 : 3 bytes */
4 /* 1111 :4 bytes */ 4 /* 1111 :4 bytes */
}; };
static const unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07}; static const unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07};
unsigned char inchar; unsigned char inchar;
SQInteger c = 0; SQInteger c = 0;
READ(iobuffer); READ(iobuffer);
c = inchar; c = inchar;
// //
if(c >= 0x80) { if(c >= 0x80) {
SQInteger tmp; SQInteger tmp;
SQInteger codelen = utf8_lengths[c>>4]; SQInteger codelen = utf8_lengths[c>>4];
if(codelen == 0) if(codelen == 0)
return 0; return 0;
//"invalid UTF-8 stream"; //"invalid UTF-8 stream";
tmp = c&byte_masks[codelen]; tmp = c&byte_masks[codelen];
for(SQInteger n = 0; n < codelen-1; n++) { for(SQInteger n = 0; n < codelen-1; n++) {
tmp<<=6; tmp<<=6;
READ(iobuffer); READ(iobuffer);
tmp |= inchar & 0x3F; tmp |= inchar & 0x3F;
} }
c = tmp; c = tmp;
} }
return c; return c;
} }
#endif #endif
static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer iobuf) static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer iobuf)
{ {
SQInteger ret; SQInteger ret;
IOBuffer *iobuffer = (IOBuffer *)iobuf; IOBuffer *iobuffer = (IOBuffer *)iobuf;
if( (ret = _read_two_bytes(iobuffer)) > 0 ) if( (ret = _read_two_bytes(iobuffer)) > 0 )
return ret; return ret;
return 0; return 0;
} }
static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer iobuf) static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer iobuf)
{ {
SQInteger c; SQInteger c;
IOBuffer *iobuffer = (IOBuffer *)iobuf; IOBuffer *iobuffer = (IOBuffer *)iobuf;
if( (c = _read_two_bytes(iobuffer)) > 0 ) { if( (c = _read_two_bytes(iobuffer)) > 0 ) {
c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00); c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00);
return c; return c;
} }
return 0; return 0;
} }
SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size) SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size)
{ {
SQInteger ret; SQInteger ret;
if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret; if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret;
return -1; return -1;
} }
SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size) SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size)
{ {
return sqstd_fwrite(p,1,size,(SQFILE)file); return sqstd_fwrite(p,1,size,(SQFILE)file);
} }
SQRESULT sqstd_loadfile(HRABBITVM v,const SQChar *filename,SQBool printerror) SQRESULT sqstd_loadfile(HRABBITVM v,const SQChar *filename,SQBool printerror)
{ {
SQFILE file = sqstd_fopen(filename,_SC("rb")); SQFILE file = sqstd_fopen(filename,_SC("rb"));
SQInteger ret; SQInteger ret;
unsigned short us; unsigned short us;
unsigned char uc; unsigned char uc;
SQLEXREADFUNC func = _io_file_lexfeed_PLAIN; SQLEXREADFUNC func = _io_file_lexfeed_PLAIN;
if(file){ if(file){
ret = sqstd_fread(&us,1,2,file); ret = sqstd_fread(&us,1,2,file);
if(ret != 2) { if(ret != 2) {
//probably an empty file //probably an empty file
us = 0; us = 0;
} }
if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE
sqstd_fseek(file,0,SQ_SEEK_SET); sqstd_fseek(file,0,SQ_SEEK_SET);
if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) { if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) {
sqstd_fclose(file); sqstd_fclose(file);
return SQ_OK; return SQ_OK;
} }
} }
else { //SCRIPT else { //SCRIPT
switch(us) switch(us)
{ {
//gotta swap the next 2 lines on BIG endian machines //gotta swap the next 2 lines on BIG endian machines
case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian; case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian;
case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian; case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian;
case 0xBBEF: case 0xBBEF:
if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) { if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) {
sqstd_fclose(file); sqstd_fclose(file);
return sq_throwerror(v,_SC("io error")); return sq_throwerror(v,_SC("io error"));
} }
if(uc != 0xBF) { if(uc != 0xBF) {
sqstd_fclose(file); sqstd_fclose(file);
return sq_throwerror(v,_SC("Unrecognized encoding")); return sq_throwerror(v,_SC("Unrecognized encoding"));
} }
#ifdef SQUNICODE #ifdef SQUNICODE
func = _io_file_lexfeed_UTF8; func = _io_file_lexfeed_UTF8;
#else #else
func = _io_file_lexfeed_PLAIN; func = _io_file_lexfeed_PLAIN;
#endif #endif
break;//UTF-8 ; break;//UTF-8 ;
default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii
} }
IOBuffer buffer; IOBuffer buffer;
buffer.ptr = 0; buffer.ptr = 0;
buffer.size = 0; buffer.size = 0;
buffer.file = file; buffer.file = file;
if(SQ_SUCCEEDED(sq_compile(v,func,&buffer,filename,printerror))){ if(SQ_SUCCEEDED(sq_compile(v,func,&buffer,filename,printerror))){
sqstd_fclose(file); sqstd_fclose(file);
return SQ_OK; return SQ_OK;
} }
} }
sqstd_fclose(file); sqstd_fclose(file);
return SQ_ERROR; return SQ_ERROR;
} }
return sq_throwerror(v,_SC("cannot open the file")); return sq_throwerror(v,_SC("cannot open the file"));
} }
SQRESULT sqstd_dofile(HRABBITVM v,const SQChar *filename,SQBool retval,SQBool printerror) SQRESULT sqstd_dofile(HRABBITVM v,const SQChar *filename,SQBool retval,SQBool printerror)
{ {
//at least one entry must exist in order for us to push it as the environment //at least one entry must exist in order for us to push it as the environment
if(sq_gettop(v) == 0) if(sq_gettop(v) == 0)
return sq_throwerror(v,_SC("environment table expected")); return sq_throwerror(v,_SC("environment table expected"));
if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) { if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) {
sq_push(v,-2); sq_push(v,-2);
if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) { if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) {
sq_remove(v,retval?-2:-1); //removes the closure sq_remove(v,retval?-2:-1); //removes the closure
return 1; return 1;
} }
sq_pop(v,1); //removes the closure sq_pop(v,1); //removes the closure
} }
return SQ_ERROR; return SQ_ERROR;
} }
SQRESULT sqstd_writeclosuretofile(HRABBITVM v,const SQChar *filename) SQRESULT sqstd_writeclosuretofile(HRABBITVM v,const SQChar *filename)
{ {
SQFILE file = sqstd_fopen(filename,_SC("wb+")); SQFILE file = sqstd_fopen(filename,_SC("wb+"));
if(!file) return sq_throwerror(v,_SC("cannot open the file")); if(!file) return sq_throwerror(v,_SC("cannot open the file"));
if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) { if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) {
sqstd_fclose(file); sqstd_fclose(file);
return SQ_OK; return SQ_OK;
} }
sqstd_fclose(file); sqstd_fclose(file);
return SQ_ERROR; //forward the error return SQ_ERROR; //forward the error
} }
SQInteger _g_io_loadfile(HRABBITVM v) SQInteger _g_io_loadfile(HRABBITVM v)
{ {
const SQChar *filename; const SQChar *filename;
SQBool printerror = SQFalse; SQBool printerror = SQFalse;
sq_getstring(v,2,&filename); sq_getstring(v,2,&filename);
if(sq_gettop(v) >= 3) { if(sq_gettop(v) >= 3) {
sq_getbool(v,3,&printerror); sq_getbool(v,3,&printerror);
} }
if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror)))
return 1; return 1;
return SQ_ERROR; //propagates the error return SQ_ERROR; //propagates the error
} }
SQInteger _g_io_writeclosuretofile(HRABBITVM v) SQInteger _g_io_writeclosuretofile(HRABBITVM v)
{ {
const SQChar *filename; const SQChar *filename;
sq_getstring(v,2,&filename); sq_getstring(v,2,&filename);
if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename))) if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename)))
return 1; return 1;
return SQ_ERROR; //propagates the error return SQ_ERROR; //propagates the error
} }
SQInteger _g_io_dofile(HRABBITVM v) SQInteger _g_io_dofile(HRABBITVM v)
{ {
const SQChar *filename; const SQChar *filename;
SQBool printerror = SQFalse; SQBool printerror = SQFalse;
sq_getstring(v,2,&filename); sq_getstring(v,2,&filename);
if(sq_gettop(v) >= 3) { if(sq_gettop(v) >= 3) {
sq_getbool(v,3,&printerror); sq_getbool(v,3,&printerror);
} }
sq_push(v,1); //repush the this sq_push(v,1); //repush the this
if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror))) if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror)))
return 1; return 1;
return SQ_ERROR; //propagates the error return SQ_ERROR; //propagates the error
} }
#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck} #define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck}
static const SQRegFunction iolib_funcs[]={ static const SQRegFunction iolib_funcs[]={
_DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")), _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")),
_DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")), _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")),
_DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")), _DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")),
{NULL,(SQFUNCTION)0,0,NULL} {NULL,(SQFUNCTION)0,0,NULL}
}; };
SQRESULT sqstd_register_iolib(HRABBITVM v) SQRESULT sqstd_register_iolib(HRABBITVM v)
{ {
SQInteger top = sq_gettop(v); SQInteger top = sq_gettop(v);
//create delegate //create delegate
declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs); declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs);
sq_pushstring(v,_SC("stdout"),-1); sq_pushstring(v,_SC("stdout"),-1);
sqstd_createfile(v,stdout,SQFalse); sqstd_createfile(v,stdout,SQFalse);
sq_newslot(v,-3,SQFalse); sq_newslot(v,-3,SQFalse);
sq_pushstring(v,_SC("stdin"),-1); sq_pushstring(v,_SC("stdin"),-1);
sqstd_createfile(v,stdin,SQFalse); sqstd_createfile(v,stdin,SQFalse);
sq_newslot(v,-3,SQFalse); sq_newslot(v,-3,SQFalse);
sq_pushstring(v,_SC("stderr"),-1); sq_pushstring(v,_SC("stderr"),-1);
sqstd_createfile(v,stderr,SQFalse); sqstd_createfile(v,stderr,SQFalse);
sq_newslot(v,-3,SQFalse); sq_newslot(v,-3,SQFalse);
sq_settop(v,top); sq_settop(v,top);
return SQ_OK; return SQ_OK;
} }

View File

@ -10,15 +10,15 @@
#define SQSTD_STREAM_TYPE_TAG 0x80000000 #define SQSTD_STREAM_TYPE_TAG 0x80000000
struct SQStream { struct SQStream {
virtual ~SQStream() {} virtual ~SQStream() {}
virtual SQInteger Read(void *buffer, SQInteger size) = 0; virtual SQInteger Read(void *buffer, SQInteger size) = 0;
virtual SQInteger Write(void *buffer, SQInteger size) = 0; virtual SQInteger Write(void *buffer, SQInteger size) = 0;
virtual SQInteger Flush() = 0; virtual SQInteger Flush() = 0;
virtual SQInteger Tell() = 0; virtual SQInteger Tell() = 0;
virtual SQInteger Len() = 0; virtual SQInteger Len() = 0;
virtual SQInteger Seek(SQInteger offset, SQInteger origin) = 0; virtual SQInteger Seek(SQInteger offset, SQInteger origin) = 0;
virtual bool IsValid() = 0; virtual bool IsValid() = 0;
virtual bool EOS() = 0; virtual bool EOS() = 0;
}; };
#define SQ_SEEK_CUR 0 #define SQ_SEEK_CUR 0

View File

@ -12,41 +12,41 @@
#include <rabbit-std/sqstdmath.hpp> #include <rabbit-std/sqstdmath.hpp>
#define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HRABBITVM v){ \ #define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HRABBITVM v){ \
SQFloat f; \ SQFloat f; \
sq_getfloat(v,2,&f); \ sq_getfloat(v,2,&f); \
sq_pushfloat(v,(SQFloat)_funcname(f)); \ sq_pushfloat(v,(SQFloat)_funcname(f)); \
return 1; \ return 1; \
} }
#define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HRABBITVM v){ \ #define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HRABBITVM v){ \
SQFloat p1,p2; \ SQFloat p1,p2; \
sq_getfloat(v,2,&p1); \ sq_getfloat(v,2,&p1); \
sq_getfloat(v,3,&p2); \ sq_getfloat(v,3,&p2); \
sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \ sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \
return 1; \ return 1; \
} }
static SQInteger math_srand(HRABBITVM v) static SQInteger math_srand(HRABBITVM v)
{ {
SQInteger i; SQInteger i;
if(SQ_FAILED(sq_getinteger(v,2,&i))) if(SQ_FAILED(sq_getinteger(v,2,&i)))
return sq_throwerror(v,_SC("invalid param")); return sq_throwerror(v,_SC("invalid param"));
srand((unsigned int)i); srand((unsigned int)i);
return 0; return 0;
} }
static SQInteger math_rand(HRABBITVM v) static SQInteger math_rand(HRABBITVM v)
{ {
sq_pushinteger(v,rand()); sq_pushinteger(v,rand());
return 1; return 1;
} }
static SQInteger math_abs(HRABBITVM v) static SQInteger math_abs(HRABBITVM v)
{ {
SQInteger n; SQInteger n;
sq_getinteger(v,2,&n); sq_getinteger(v,2,&n);
sq_pushinteger(v,(SQInteger)abs((int)n)); sq_pushinteger(v,(SQInteger)abs((int)n));
return 1; return 1;
} }
SINGLE_ARG_FUNC(sqrt) SINGLE_ARG_FUNC(sqrt)
@ -67,25 +67,25 @@ SINGLE_ARG_FUNC(exp)
#define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck} #define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck}
static const SQRegFunction mathlib_funcs[] = { static const SQRegFunction mathlib_funcs[] = {
_DECL_FUNC(sqrt,2,_SC(".n")), _DECL_FUNC(sqrt,2,_SC(".n")),
_DECL_FUNC(sin,2,_SC(".n")), _DECL_FUNC(sin,2,_SC(".n")),
_DECL_FUNC(cos,2,_SC(".n")), _DECL_FUNC(cos,2,_SC(".n")),
_DECL_FUNC(asin,2,_SC(".n")), _DECL_FUNC(asin,2,_SC(".n")),
_DECL_FUNC(acos,2,_SC(".n")), _DECL_FUNC(acos,2,_SC(".n")),
_DECL_FUNC(log,2,_SC(".n")), _DECL_FUNC(log,2,_SC(".n")),
_DECL_FUNC(log10,2,_SC(".n")), _DECL_FUNC(log10,2,_SC(".n")),
_DECL_FUNC(tan,2,_SC(".n")), _DECL_FUNC(tan,2,_SC(".n")),
_DECL_FUNC(atan,2,_SC(".n")), _DECL_FUNC(atan,2,_SC(".n")),
_DECL_FUNC(atan2,3,_SC(".nn")), _DECL_FUNC(atan2,3,_SC(".nn")),
_DECL_FUNC(pow,3,_SC(".nn")), _DECL_FUNC(pow,3,_SC(".nn")),
_DECL_FUNC(floor,2,_SC(".n")), _DECL_FUNC(floor,2,_SC(".n")),
_DECL_FUNC(ceil,2,_SC(".n")), _DECL_FUNC(ceil,2,_SC(".n")),
_DECL_FUNC(exp,2,_SC(".n")), _DECL_FUNC(exp,2,_SC(".n")),
_DECL_FUNC(srand,2,_SC(".n")), _DECL_FUNC(srand,2,_SC(".n")),
_DECL_FUNC(rand,1,NULL), _DECL_FUNC(rand,1,NULL),
_DECL_FUNC(fabs,2,_SC(".n")), _DECL_FUNC(fabs,2,_SC(".n")),
_DECL_FUNC(abs,2,_SC(".n")), _DECL_FUNC(abs,2,_SC(".n")),
{NULL,(SQFUNCTION)0,0,NULL} {NULL,(SQFUNCTION)0,0,NULL}
}; };
#undef _DECL_FUNC #undef _DECL_FUNC
@ -95,20 +95,20 @@ static const SQRegFunction mathlib_funcs[] = {
SQRESULT sqstd_register_mathlib(HRABBITVM v) SQRESULT sqstd_register_mathlib(HRABBITVM v)
{ {
SQInteger i=0; SQInteger i=0;
while(mathlib_funcs[i].name!=0) { while(mathlib_funcs[i].name!=0) {
sq_pushstring(v,mathlib_funcs[i].name,-1); sq_pushstring(v,mathlib_funcs[i].name,-1);
sq_newclosure(v,mathlib_funcs[i].f,0); sq_newclosure(v,mathlib_funcs[i].f,0);
sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask); sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask);
sq_setnativeclosurename(v,-1,mathlib_funcs[i].name); sq_setnativeclosurename(v,-1,mathlib_funcs[i].name);
sq_newslot(v,-3,SQFalse); sq_newslot(v,-3,SQFalse);
i++; i++;
} }
sq_pushstring(v,_SC("RAND_MAX"),-1); sq_pushstring(v,_SC("RAND_MAX"),-1);
sq_pushinteger(v,RAND_MAX); sq_pushinteger(v,RAND_MAX);
sq_newslot(v,-3,SQFalse); sq_newslot(v,-3,SQFalse);
sq_pushstring(v,_SC("PI"),-1); sq_pushstring(v,_SC("PI"),-1);
sq_pushfloat(v,(SQFloat)M_PI); sq_pushfloat(v,(SQFloat)M_PI);
sq_newslot(v,-3,SQFalse); sq_newslot(v,-3,SQFalse);
return SQ_OK; return SQ_OK;
} }

File diff suppressed because it is too large Load Diff

View File

@ -17,327 +17,327 @@
#include <rabbit-std/sqstdblobimpl.hpp> #include <rabbit-std/sqstdblobimpl.hpp>
#define SETUP_STREAM(v) \ #define SETUP_STREAM(v) \
SQStream *self = NULL; \ SQStream *self = NULL; \
if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)((SQUnsignedInteger)SQSTD_STREAM_TYPE_TAG)))) \ if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)((SQUnsignedInteger)SQSTD_STREAM_TYPE_TAG)))) \
return sq_throwerror(v,_SC("invalid type tag")); \ return sq_throwerror(v,_SC("invalid type tag")); \
if(!self || !self->IsValid()) \ if(!self || !self->IsValid()) \
return sq_throwerror(v,_SC("the stream is invalid")); return sq_throwerror(v,_SC("the stream is invalid"));
SQInteger _stream_readblob(HRABBITVM v) SQInteger _stream_readblob(HRABBITVM v)
{ {
SETUP_STREAM(v); SETUP_STREAM(v);
SQUserPointer data,blobp; SQUserPointer data,blobp;
SQInteger size,res; SQInteger size,res;
sq_getinteger(v,2,&size); sq_getinteger(v,2,&size);
if(size > self->Len()) { if(size > self->Len()) {
size = self->Len(); size = self->Len();
} }
data = sq_getscratchpad(v,size); data = sq_getscratchpad(v,size);
res = self->Read(data,size); res = self->Read(data,size);
if(res <= 0) if(res <= 0)
return sq_throwerror(v,_SC("no data left to read")); return sq_throwerror(v,_SC("no data left to read"));
blobp = sqstd_createblob(v,res); blobp = sqstd_createblob(v,res);
memcpy(blobp,data,res); memcpy(blobp,data,res);
return 1; return 1;
} }
#define SAFE_READN(ptr,len) { \ #define SAFE_READN(ptr,len) { \
if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \ if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \
} }
SQInteger _stream_readn(HRABBITVM v) SQInteger _stream_readn(HRABBITVM v)
{ {
SETUP_STREAM(v); SETUP_STREAM(v);
SQInteger format; SQInteger format;
sq_getinteger(v, 2, &format); sq_getinteger(v, 2, &format);
switch(format) { switch(format) {
case 'l': { case 'l': {
SQInteger i; SQInteger i;
SAFE_READN(&i, sizeof(i)); SAFE_READN(&i, sizeof(i));
sq_pushinteger(v, i); sq_pushinteger(v, i);
} }
break; break;
case 'i': { case 'i': {
SQInt32 i; SQInt32 i;
SAFE_READN(&i, sizeof(i)); SAFE_READN(&i, sizeof(i));
sq_pushinteger(v, i); sq_pushinteger(v, i);
} }
break; break;
case 's': { case 's': {
short s; short s;
SAFE_READN(&s, sizeof(short)); SAFE_READN(&s, sizeof(short));
sq_pushinteger(v, s); sq_pushinteger(v, s);
} }
break; break;
case 'w': { case 'w': {
unsigned short w; unsigned short w;
SAFE_READN(&w, sizeof(unsigned short)); SAFE_READN(&w, sizeof(unsigned short));
sq_pushinteger(v, w); sq_pushinteger(v, w);
} }
break; break;
case 'c': { case 'c': {
char c; char c;
SAFE_READN(&c, sizeof(char)); SAFE_READN(&c, sizeof(char));
sq_pushinteger(v, c); sq_pushinteger(v, c);
} }
break; break;
case 'b': { case 'b': {
unsigned char c; unsigned char c;
SAFE_READN(&c, sizeof(unsigned char)); SAFE_READN(&c, sizeof(unsigned char));
sq_pushinteger(v, c); sq_pushinteger(v, c);
} }
break; break;
case 'f': { case 'f': {
float f; float f;
SAFE_READN(&f, sizeof(float)); SAFE_READN(&f, sizeof(float));
sq_pushfloat(v, f); sq_pushfloat(v, f);
} }
break; break;
case 'd': { case 'd': {
double d; double d;
SAFE_READN(&d, sizeof(double)); SAFE_READN(&d, sizeof(double));
sq_pushfloat(v, (SQFloat)d); sq_pushfloat(v, (SQFloat)d);
} }
break; break;
default: default:
return sq_throwerror(v, _SC("invalid format")); return sq_throwerror(v, _SC("invalid format"));
} }
return 1; return 1;
} }
SQInteger _stream_writeblob(HRABBITVM v) SQInteger _stream_writeblob(HRABBITVM v)
{ {
SQUserPointer data; SQUserPointer data;
SQInteger size; SQInteger size;
SETUP_STREAM(v); SETUP_STREAM(v);
if(SQ_FAILED(sqstd_getblob(v,2,&data))) if(SQ_FAILED(sqstd_getblob(v,2,&data)))
return sq_throwerror(v,_SC("invalid parameter")); return sq_throwerror(v,_SC("invalid parameter"));
size = sqstd_getblobsize(v,2); size = sqstd_getblobsize(v,2);
if(self->Write(data,size) != size) if(self->Write(data,size) != size)
return sq_throwerror(v,_SC("io error")); return sq_throwerror(v,_SC("io error"));
sq_pushinteger(v,size); sq_pushinteger(v,size);
return 1; return 1;
} }
SQInteger _stream_writen(HRABBITVM v) SQInteger _stream_writen(HRABBITVM v)
{ {
SETUP_STREAM(v); SETUP_STREAM(v);
SQInteger format, ti; SQInteger format, ti;
SQFloat tf; SQFloat tf;
sq_getinteger(v, 3, &format); sq_getinteger(v, 3, &format);
switch(format) { switch(format) {
case 'l': { case 'l': {
SQInteger i; SQInteger i;
sq_getinteger(v, 2, &ti); sq_getinteger(v, 2, &ti);
i = ti; i = ti;
self->Write(&i, sizeof(SQInteger)); self->Write(&i, sizeof(SQInteger));
} }
break; break;
case 'i': { case 'i': {
SQInt32 i; SQInt32 i;
sq_getinteger(v, 2, &ti); sq_getinteger(v, 2, &ti);
i = (SQInt32)ti; i = (SQInt32)ti;
self->Write(&i, sizeof(SQInt32)); self->Write(&i, sizeof(SQInt32));
} }
break; break;
case 's': { case 's': {
short s; short s;
sq_getinteger(v, 2, &ti); sq_getinteger(v, 2, &ti);
s = (short)ti; s = (short)ti;
self->Write(&s, sizeof(short)); self->Write(&s, sizeof(short));
} }
break; break;
case 'w': { case 'w': {
unsigned short w; unsigned short w;
sq_getinteger(v, 2, &ti); sq_getinteger(v, 2, &ti);
w = (unsigned short)ti; w = (unsigned short)ti;
self->Write(&w, sizeof(unsigned short)); self->Write(&w, sizeof(unsigned short));
} }
break; break;
case 'c': { case 'c': {
char c; char c;
sq_getinteger(v, 2, &ti); sq_getinteger(v, 2, &ti);
c = (char)ti; c = (char)ti;
self->Write(&c, sizeof(char)); self->Write(&c, sizeof(char));
} }
break; break;
case 'b': { case 'b': {
unsigned char b; unsigned char b;
sq_getinteger(v, 2, &ti); sq_getinteger(v, 2, &ti);
b = (unsigned char)ti; b = (unsigned char)ti;
self->Write(&b, sizeof(unsigned char)); self->Write(&b, sizeof(unsigned char));
} }
break; break;
case 'f': { case 'f': {
float f; float f;
sq_getfloat(v, 2, &tf); sq_getfloat(v, 2, &tf);
f = (float)tf; f = (float)tf;
self->Write(&f, sizeof(float)); self->Write(&f, sizeof(float));
} }
break; break;
case 'd': { case 'd': {
double d; double d;
sq_getfloat(v, 2, &tf); sq_getfloat(v, 2, &tf);
d = tf; d = tf;
self->Write(&d, sizeof(double)); self->Write(&d, sizeof(double));
} }
break; break;
default: default:
return sq_throwerror(v, _SC("invalid format")); return sq_throwerror(v, _SC("invalid format"));
} }
return 0; return 0;
} }
SQInteger _stream_seek(HRABBITVM v) SQInteger _stream_seek(HRABBITVM v)
{ {
SETUP_STREAM(v); SETUP_STREAM(v);
SQInteger offset, origin = SQ_SEEK_SET; SQInteger offset, origin = SQ_SEEK_SET;
sq_getinteger(v, 2, &offset); sq_getinteger(v, 2, &offset);
if(sq_gettop(v) > 2) { if(sq_gettop(v) > 2) {
SQInteger t; SQInteger t;
sq_getinteger(v, 3, &t); sq_getinteger(v, 3, &t);
switch(t) { switch(t) {
case 'b': origin = SQ_SEEK_SET; break; case 'b': origin = SQ_SEEK_SET; break;
case 'c': origin = SQ_SEEK_CUR; break; case 'c': origin = SQ_SEEK_CUR; break;
case 'e': origin = SQ_SEEK_END; break; case 'e': origin = SQ_SEEK_END; break;
default: return sq_throwerror(v,_SC("invalid origin")); default: return sq_throwerror(v,_SC("invalid origin"));
} }
} }
sq_pushinteger(v, self->Seek(offset, origin)); sq_pushinteger(v, self->Seek(offset, origin));
return 1; return 1;
} }
SQInteger _stream_tell(HRABBITVM v) SQInteger _stream_tell(HRABBITVM v)
{ {
SETUP_STREAM(v); SETUP_STREAM(v);
sq_pushinteger(v, self->Tell()); sq_pushinteger(v, self->Tell());
return 1; return 1;
} }
SQInteger _stream_len(HRABBITVM v) SQInteger _stream_len(HRABBITVM v)
{ {
SETUP_STREAM(v); SETUP_STREAM(v);
sq_pushinteger(v, self->Len()); sq_pushinteger(v, self->Len());
return 1; return 1;
} }
SQInteger _stream_flush(HRABBITVM v) SQInteger _stream_flush(HRABBITVM v)
{ {
SETUP_STREAM(v); SETUP_STREAM(v);
if(!self->Flush()) if(!self->Flush())
sq_pushinteger(v, 1); sq_pushinteger(v, 1);
else else
sq_pushnull(v); sq_pushnull(v);
return 1; return 1;
} }
SQInteger _stream_eos(HRABBITVM v) SQInteger _stream_eos(HRABBITVM v)
{ {
SETUP_STREAM(v); SETUP_STREAM(v);
if(self->EOS()) if(self->EOS())
sq_pushinteger(v, 1); sq_pushinteger(v, 1);
else else
sq_pushnull(v); sq_pushnull(v);
return 1; return 1;
} }
SQInteger _stream__cloned(HRABBITVM v) SQInteger _stream__cloned(HRABBITVM v)
{ {
return sq_throwerror(v,_SC("this object cannot be cloned")); return sq_throwerror(v,_SC("this object cannot be cloned"));
} }
static const SQRegFunction _stream_methods[] = { static const SQRegFunction _stream_methods[] = {
_DECL_STREAM_FUNC(readblob,2,_SC("xn")), _DECL_STREAM_FUNC(readblob,2,_SC("xn")),
_DECL_STREAM_FUNC(readn,2,_SC("xn")), _DECL_STREAM_FUNC(readn,2,_SC("xn")),
_DECL_STREAM_FUNC(writeblob,-2,_SC("xx")), _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")),
_DECL_STREAM_FUNC(writen,3,_SC("xnn")), _DECL_STREAM_FUNC(writen,3,_SC("xnn")),
_DECL_STREAM_FUNC(seek,-2,_SC("xnn")), _DECL_STREAM_FUNC(seek,-2,_SC("xnn")),
_DECL_STREAM_FUNC(tell,1,_SC("x")), _DECL_STREAM_FUNC(tell,1,_SC("x")),
_DECL_STREAM_FUNC(len,1,_SC("x")), _DECL_STREAM_FUNC(len,1,_SC("x")),
_DECL_STREAM_FUNC(eos,1,_SC("x")), _DECL_STREAM_FUNC(eos,1,_SC("x")),
_DECL_STREAM_FUNC(flush,1,_SC("x")), _DECL_STREAM_FUNC(flush,1,_SC("x")),
_DECL_STREAM_FUNC(_cloned,0,NULL), _DECL_STREAM_FUNC(_cloned,0,NULL),
{NULL,(SQFUNCTION)0,0,NULL} {NULL,(SQFUNCTION)0,0,NULL}
}; };
void init_streamclass(HRABBITVM v) void init_streamclass(HRABBITVM v)
{ {
sq_pushregistrytable(v); sq_pushregistrytable(v);
sq_pushstring(v,_SC("std_stream"),-1); sq_pushstring(v,_SC("std_stream"),-1);
if(SQ_FAILED(sq_get(v,-2))) { if(SQ_FAILED(sq_get(v,-2))) {
sq_pushstring(v,_SC("std_stream"),-1); sq_pushstring(v,_SC("std_stream"),-1);
sq_newclass(v,SQFalse); sq_newclass(v,SQFalse);
sq_settypetag(v,-1,(SQUserPointer)((SQUnsignedInteger)SQSTD_STREAM_TYPE_TAG)); sq_settypetag(v,-1,(SQUserPointer)((SQUnsignedInteger)SQSTD_STREAM_TYPE_TAG));
SQInteger i = 0; SQInteger i = 0;
while(_stream_methods[i].name != 0) { while(_stream_methods[i].name != 0) {
const SQRegFunction &f = _stream_methods[i]; const SQRegFunction &f = _stream_methods[i];
sq_pushstring(v,f.name,-1); sq_pushstring(v,f.name,-1);
sq_newclosure(v,f.f,0); sq_newclosure(v,f.f,0);
sq_setparamscheck(v,f.nparamscheck,f.typemask); sq_setparamscheck(v,f.nparamscheck,f.typemask);
sq_newslot(v,-3,SQFalse); sq_newslot(v,-3,SQFalse);
i++; i++;
} }
sq_newslot(v,-3,SQFalse); sq_newslot(v,-3,SQFalse);
sq_pushroottable(v); sq_pushroottable(v);
sq_pushstring(v,_SC("stream"),-1); sq_pushstring(v,_SC("stream"),-1);
sq_pushstring(v,_SC("std_stream"),-1); sq_pushstring(v,_SC("std_stream"),-1);
sq_get(v,-4); sq_get(v,-4);
sq_newslot(v,-3,SQFalse); sq_newslot(v,-3,SQFalse);
sq_pop(v,1); sq_pop(v,1);
} }
else { else {
sq_pop(v,1); //result sq_pop(v,1); //result
} }
sq_pop(v,1); sq_pop(v,1);
} }
SQRESULT declare_stream(HRABBITVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,const SQRegFunction *methods,const SQRegFunction *globals) SQRESULT declare_stream(HRABBITVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,const SQRegFunction *methods,const SQRegFunction *globals)
{ {
if(sq_gettype(v,-1) != OT_TABLE) if(sq_gettype(v,-1) != OT_TABLE)
return sq_throwerror(v,_SC("table expected")); return sq_throwerror(v,_SC("table expected"));
SQInteger top = sq_gettop(v); SQInteger top = sq_gettop(v);
//create delegate //create delegate
init_streamclass(v); init_streamclass(v);
sq_pushregistrytable(v); sq_pushregistrytable(v);
sq_pushstring(v,reg_name,-1); sq_pushstring(v,reg_name,-1);
sq_pushstring(v,_SC("std_stream"),-1); sq_pushstring(v,_SC("std_stream"),-1);
if(SQ_SUCCEEDED(sq_get(v,-3))) { if(SQ_SUCCEEDED(sq_get(v,-3))) {
sq_newclass(v,SQTrue); sq_newclass(v,SQTrue);
sq_settypetag(v,-1,typetag); sq_settypetag(v,-1,typetag);
SQInteger i = 0; SQInteger i = 0;
while(methods[i].name != 0) { while(methods[i].name != 0) {
const SQRegFunction &f = methods[i]; const SQRegFunction &f = methods[i];
sq_pushstring(v,f.name,-1); sq_pushstring(v,f.name,-1);
sq_newclosure(v,f.f,0); sq_newclosure(v,f.f,0);
sq_setparamscheck(v,f.nparamscheck,f.typemask); sq_setparamscheck(v,f.nparamscheck,f.typemask);
sq_setnativeclosurename(v,-1,f.name); sq_setnativeclosurename(v,-1,f.name);
sq_newslot(v,-3,SQFalse); sq_newslot(v,-3,SQFalse);
i++; i++;
} }
sq_newslot(v,-3,SQFalse); sq_newslot(v,-3,SQFalse);
sq_pop(v,1); sq_pop(v,1);
i = 0; i = 0;
while(globals[i].name!=0) while(globals[i].name!=0)
{ {
const SQRegFunction &f = globals[i]; const SQRegFunction &f = globals[i];
sq_pushstring(v,f.name,-1); sq_pushstring(v,f.name,-1);
sq_newclosure(v,f.f,0); sq_newclosure(v,f.f,0);
sq_setparamscheck(v,f.nparamscheck,f.typemask); sq_setparamscheck(v,f.nparamscheck,f.typemask);
sq_setnativeclosurename(v,-1,f.name); sq_setnativeclosurename(v,-1,f.name);
sq_newslot(v,-3,SQFalse); sq_newslot(v,-3,SQFalse);
i++; i++;
} }
//register the class in the target table //register the class in the target table
sq_pushstring(v,name,-1); sq_pushstring(v,name,-1);
sq_pushregistrytable(v); sq_pushregistrytable(v);
sq_pushstring(v,reg_name,-1); sq_pushstring(v,reg_name,-1);
sq_get(v,-2); sq_get(v,-2);
sq_remove(v,-2); sq_remove(v,-2);
sq_newslot(v,-3,SQFalse); sq_newslot(v,-3,SQFalse);
sq_settop(v,top); sq_settop(v,top);
return SQ_OK; return SQ_OK;
} }
sq_settop(v,top); sq_settop(v,top);
return SQ_ERROR; return SQ_ERROR;
} }

View File

@ -20,506 +20,506 @@
static SQBool isfmtchr(SQChar ch) static SQBool isfmtchr(SQChar ch)
{ {
switch(ch) { switch(ch) {
case '-': case '+': case ' ': case '#': case '0': return SQTrue; case '-': case '+': case ' ': case '#': case '0': return SQTrue;
} }
return SQFalse; return SQFalse;
} }
static SQInteger validate_format(HRABBITVM v, SQChar *fmt, const SQChar *src, SQInteger n,SQInteger &width) static SQInteger validate_format(HRABBITVM v, SQChar *fmt, const SQChar *src, SQInteger n,SQInteger &width)
{ {
SQChar *dummy; SQChar *dummy;
SQChar swidth[MAX_WFORMAT_LEN]; SQChar swidth[MAX_WFORMAT_LEN];
SQInteger wc = 0; SQInteger wc = 0;
SQInteger start = n; SQInteger start = n;
fmt[0] = '%'; fmt[0] = '%';
while (isfmtchr(src[n])) n++; while (isfmtchr(src[n])) n++;
while (scisdigit(src[n])) { while (scisdigit(src[n])) {
swidth[wc] = src[n]; swidth[wc] = src[n];
n++; n++;
wc++; wc++;
if(wc>=MAX_WFORMAT_LEN) if(wc>=MAX_WFORMAT_LEN)
return sq_throwerror(v,_SC("width format too long")); return sq_throwerror(v,_SC("width format too long"));
} }
swidth[wc] = '\0'; swidth[wc] = '\0';
if(wc > 0) { if(wc > 0) {
width = scstrtol(swidth,&dummy,10); width = scstrtol(swidth,&dummy,10);
} }
else else
width = 0; width = 0;
if (src[n] == '.') { if (src[n] == '.') {
n++; n++;
wc = 0; wc = 0;
while (scisdigit(src[n])) { while (scisdigit(src[n])) {
swidth[wc] = src[n]; swidth[wc] = src[n];
n++; n++;
wc++; wc++;
if(wc>=MAX_WFORMAT_LEN) if(wc>=MAX_WFORMAT_LEN)
return sq_throwerror(v,_SC("precision format too long")); return sq_throwerror(v,_SC("precision format too long"));
} }
swidth[wc] = '\0'; swidth[wc] = '\0';
if(wc > 0) { if(wc > 0) {
width += scstrtol(swidth,&dummy,10); width += scstrtol(swidth,&dummy,10);
} }
} }
if (n-start > MAX_FORMAT_LEN ) if (n-start > MAX_FORMAT_LEN )
return sq_throwerror(v,_SC("format too long")); return sq_throwerror(v,_SC("format too long"));
memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar)); memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar));
fmt[(n-start)+2] = '\0'; fmt[(n-start)+2] = '\0';
return n; return n;
} }
SQRESULT sqstd_format(HRABBITVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output) SQRESULT sqstd_format(HRABBITVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output)
{ {
const SQChar *format; const SQChar *format;
SQChar *dest; SQChar *dest;
SQChar fmt[MAX_FORMAT_LEN]; SQChar fmt[MAX_FORMAT_LEN];
const SQRESULT res = sq_getstring(v,nformatstringidx,&format); const SQRESULT res = sq_getstring(v,nformatstringidx,&format);
if (SQ_FAILED(res)) { if (SQ_FAILED(res)) {
return res; // propagate the error return res; // propagate the error
} }
SQInteger format_size = sq_getsize(v,nformatstringidx); SQInteger format_size = sq_getsize(v,nformatstringidx);
SQInteger allocated = (format_size+2)*sizeof(SQChar); SQInteger allocated = (format_size+2)*sizeof(SQChar);
dest = sq_getscratchpad(v,allocated); dest = sq_getscratchpad(v,allocated);
SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0; SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0;
//while(format[n] != '\0') //while(format[n] != '\0')
while(n < format_size) while(n < format_size)
{ {
if(format[n] != '%') { if(format[n] != '%') {
assert(i < allocated); assert(i < allocated);
dest[i++] = format[n]; dest[i++] = format[n];
n++; n++;
} }
else if(format[n+1] == '%') { //handles %% else if(format[n+1] == '%') { //handles %%
dest[i++] = '%'; dest[i++] = '%';
n += 2; n += 2;
} }
else { else {
n++; n++;
if( nparam > sq_gettop(v) ) if( nparam > sq_gettop(v) )
return sq_throwerror(v,_SC("not enough parameters for the given format string")); return sq_throwerror(v,_SC("not enough parameters for the given format string"));
n = validate_format(v,fmt,format,n,w); n = validate_format(v,fmt,format,n,w);
if(n < 0) return -1; if(n < 0) return -1;
SQInteger addlen = 0; SQInteger addlen = 0;
SQInteger valtype = 0; SQInteger valtype = 0;
const SQChar *ts = NULL; const SQChar *ts = NULL;
SQInteger ti = 0; SQInteger ti = 0;
SQFloat tf = 0; SQFloat tf = 0;
switch(format[n]) { switch(format[n]) {
case 's': case 's':
if(SQ_FAILED(sq_getstring(v,nparam,&ts))) if(SQ_FAILED(sq_getstring(v,nparam,&ts)))
return sq_throwerror(v,_SC("string expected for the specified format")); return sq_throwerror(v,_SC("string expected for the specified format"));
addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar)); addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar));
valtype = 's'; valtype = 's';
break; break;
case 'i': case 'd': case 'o': case 'u': case 'x': case 'X': case 'i': case 'd': case 'o': case 'u': case 'x': case 'X':
#ifdef _SQ64 #ifdef _SQ64
{ {
size_t flen = scstrlen(fmt); size_t flen = scstrlen(fmt);
SQInteger fpos = flen - 1; SQInteger fpos = flen - 1;
SQChar f = fmt[fpos]; SQChar f = fmt[fpos];
const SQChar *prec = (const SQChar *)_PRINT_INT_PREC; const SQChar *prec = (const SQChar *)_PRINT_INT_PREC;
while(*prec != _SC('\0')) { while(*prec != _SC('\0')) {
fmt[fpos++] = *prec++; fmt[fpos++] = *prec++;
} }
fmt[fpos++] = f; fmt[fpos++] = f;
fmt[fpos++] = _SC('\0'); fmt[fpos++] = _SC('\0');
} }
#endif #endif
case 'c': case 'c':
if(SQ_FAILED(sq_getinteger(v,nparam,&ti))) if(SQ_FAILED(sq_getinteger(v,nparam,&ti)))
return sq_throwerror(v,_SC("integer expected for the specified format")); return sq_throwerror(v,_SC("integer expected for the specified format"));
addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar)); addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
valtype = 'i'; valtype = 'i';
break; break;
case 'f': case 'g': case 'G': case 'e': case 'E': case 'f': case 'g': case 'G': case 'e': case 'E':
if(SQ_FAILED(sq_getfloat(v,nparam,&tf))) if(SQ_FAILED(sq_getfloat(v,nparam,&tf)))
return sq_throwerror(v,_SC("float expected for the specified format")); return sq_throwerror(v,_SC("float expected for the specified format"));
addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar)); addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
valtype = 'f'; valtype = 'f';
break; break;
default: default:
return sq_throwerror(v,_SC("invalid format")); return sq_throwerror(v,_SC("invalid format"));
} }
n++; n++;
allocated += addlen + sizeof(SQChar); allocated += addlen + sizeof(SQChar);
dest = sq_getscratchpad(v,allocated); dest = sq_getscratchpad(v,allocated);
switch(valtype) { switch(valtype) {
case 's': i += scsprintf(&dest[i],allocated,fmt,ts); break; case 's': i += scsprintf(&dest[i],allocated,fmt,ts); break;
case 'i': i += scsprintf(&dest[i],allocated,fmt,ti); break; case 'i': i += scsprintf(&dest[i],allocated,fmt,ti); break;
case 'f': i += scsprintf(&dest[i],allocated,fmt,tf); break; case 'f': i += scsprintf(&dest[i],allocated,fmt,tf); break;
}; };
nparam ++; nparam ++;
} }
} }
*outlen = i; *outlen = i;
dest[i] = '\0'; dest[i] = '\0';
*output = dest; *output = dest;
return SQ_OK; return SQ_OK;
} }
static SQInteger _string_printf(HRABBITVM v) static SQInteger _string_printf(HRABBITVM v)
{ {
SQChar *dest = NULL; SQChar *dest = NULL;
SQInteger length = 0; SQInteger length = 0;
if(SQ_FAILED(sqstd_format(v,2,&length,&dest))) if(SQ_FAILED(sqstd_format(v,2,&length,&dest)))
return -1; return -1;
SQPRINTFUNCTION printfunc = sq_getprintfunc(v); SQPRINTFUNCTION printfunc = sq_getprintfunc(v);
if(printfunc) printfunc(v,dest); if(printfunc) printfunc(v,dest);
return 0; return 0;
} }
static SQInteger _string_format(HRABBITVM v) static SQInteger _string_format(HRABBITVM v)
{ {
SQChar *dest = NULL; SQChar *dest = NULL;
SQInteger length = 0; SQInteger length = 0;
if(SQ_FAILED(sqstd_format(v,2,&length,&dest))) if(SQ_FAILED(sqstd_format(v,2,&length,&dest)))
return -1; return -1;
sq_pushstring(v,dest,length); sq_pushstring(v,dest,length);
return 1; return 1;
} }
static void __strip_l(const SQChar *str,const SQChar **start) static void __strip_l(const SQChar *str,const SQChar **start)
{ {
const SQChar *t = str; const SQChar *t = str;
while(((*t) != '\0') && scisspace(*t)){ t++; } while(((*t) != '\0') && scisspace(*t)){ t++; }
*start = t; *start = t;
} }
static void __strip_r(const SQChar *str,SQInteger len,const SQChar **end) static void __strip_r(const SQChar *str,SQInteger len,const SQChar **end)
{ {
if(len == 0) { if(len == 0) {
*end = str; *end = str;
return; return;
} }
const SQChar *t = &str[len-1]; const SQChar *t = &str[len-1];
while(t >= str && scisspace(*t)) { t--; } while(t >= str && scisspace(*t)) { t--; }
*end = t + 1; *end = t + 1;
} }
static SQInteger _string_strip(HRABBITVM v) static SQInteger _string_strip(HRABBITVM v)
{ {
const SQChar *str,*start,*end; const SQChar *str,*start,*end;
sq_getstring(v,2,&str); sq_getstring(v,2,&str);
SQInteger len = sq_getsize(v,2); SQInteger len = sq_getsize(v,2);
__strip_l(str,&start); __strip_l(str,&start);
__strip_r(str,len,&end); __strip_r(str,len,&end);
sq_pushstring(v,start,end - start); sq_pushstring(v,start,end - start);
return 1; return 1;
} }
static SQInteger _string_lstrip(HRABBITVM v) static SQInteger _string_lstrip(HRABBITVM v)
{ {
const SQChar *str,*start; const SQChar *str,*start;
sq_getstring(v,2,&str); sq_getstring(v,2,&str);
__strip_l(str,&start); __strip_l(str,&start);
sq_pushstring(v,start,-1); sq_pushstring(v,start,-1);
return 1; return 1;
} }
static SQInteger _string_rstrip(HRABBITVM v) static SQInteger _string_rstrip(HRABBITVM v)
{ {
const SQChar *str,*end; const SQChar *str,*end;
sq_getstring(v,2,&str); sq_getstring(v,2,&str);
SQInteger len = sq_getsize(v,2); SQInteger len = sq_getsize(v,2);
__strip_r(str,len,&end); __strip_r(str,len,&end);
sq_pushstring(v,str,end - str); sq_pushstring(v,str,end - str);
return 1; return 1;
} }
static SQInteger _string_split(HRABBITVM v) static SQInteger _string_split(HRABBITVM v)
{ {
const SQChar *str,*seps; const SQChar *str,*seps;
SQChar *stemp; SQChar *stemp;
sq_getstring(v,2,&str); sq_getstring(v,2,&str);
sq_getstring(v,3,&seps); sq_getstring(v,3,&seps);
SQInteger sepsize = sq_getsize(v,3); SQInteger sepsize = sq_getsize(v,3);
if(sepsize == 0) return sq_throwerror(v,_SC("empty separators string")); if(sepsize == 0) return sq_throwerror(v,_SC("empty separators string"));
SQInteger memsize = (sq_getsize(v,2)+1)*sizeof(SQChar); SQInteger memsize = (sq_getsize(v,2)+1)*sizeof(SQChar);
stemp = sq_getscratchpad(v,memsize); stemp = sq_getscratchpad(v,memsize);
memcpy(stemp,str,memsize); memcpy(stemp,str,memsize);
SQChar *start = stemp; SQChar *start = stemp;
SQChar *end = stemp; SQChar *end = stemp;
sq_newarray(v,0); sq_newarray(v,0);
while(*end != '\0') while(*end != '\0')
{ {
SQChar cur = *end; SQChar cur = *end;
for(SQInteger i = 0; i < sepsize; i++) for(SQInteger i = 0; i < sepsize; i++)
{ {
if(cur == seps[i]) if(cur == seps[i])
{ {
*end = 0; *end = 0;
sq_pushstring(v,start,-1); sq_pushstring(v,start,-1);
sq_arrayappend(v,-2); sq_arrayappend(v,-2);
start = end + 1; start = end + 1;
break; break;
} }
} }
end++; end++;
} }
if(end != start) if(end != start)
{ {
sq_pushstring(v,start,-1); sq_pushstring(v,start,-1);
sq_arrayappend(v,-2); sq_arrayappend(v,-2);
} }
return 1; return 1;
} }
static SQInteger _string_escape(HRABBITVM v) static SQInteger _string_escape(HRABBITVM v)
{ {
const SQChar *str; const SQChar *str;
SQChar *dest,*resstr; SQChar *dest,*resstr;
SQInteger size; SQInteger size;
sq_getstring(v,2,&str); sq_getstring(v,2,&str);
size = sq_getsize(v,2); size = sq_getsize(v,2);
if(size == 0) { if(size == 0) {
sq_push(v,2); sq_push(v,2);
return 1; return 1;
} }
#ifdef SQUNICODE #ifdef SQUNICODE
#if WCHAR_SIZE == 2 #if WCHAR_SIZE == 2
const SQChar *escpat = _SC("\\x%04x"); const SQChar *escpat = _SC("\\x%04x");
const SQInteger maxescsize = 6; const SQInteger maxescsize = 6;
#else //WCHAR_SIZE == 4 #else //WCHAR_SIZE == 4
const SQChar *escpat = _SC("\\x%08x"); const SQChar *escpat = _SC("\\x%08x");
const SQInteger maxescsize = 10; const SQInteger maxescsize = 10;
#endif #endif
#else #else
const SQChar *escpat = _SC("\\x%02x"); const SQChar *escpat = _SC("\\x%02x");
const SQInteger maxescsize = 4; const SQInteger maxescsize = 4;
#endif #endif
SQInteger destcharsize = (size * maxescsize); //assumes every char could be escaped SQInteger destcharsize = (size * maxescsize); //assumes every char could be escaped
resstr = dest = (SQChar *)sq_getscratchpad(v,destcharsize * sizeof(SQChar)); resstr = dest = (SQChar *)sq_getscratchpad(v,destcharsize * sizeof(SQChar));
SQChar c; SQChar c;
SQChar escch; SQChar escch;
SQInteger escaped = 0; SQInteger escaped = 0;
for(int n = 0; n < size; n++){ for(int n = 0; n < size; n++){
c = *str++; c = *str++;
escch = 0; escch = 0;
if(scisprint(c) || c == 0) { if(scisprint(c) || c == 0) {
switch(c) { switch(c) {
case '\a': escch = 'a'; break; case '\a': escch = 'a'; break;
case '\b': escch = 'b'; break; case '\b': escch = 'b'; break;
case '\t': escch = 't'; break; case '\t': escch = 't'; break;
case '\n': escch = 'n'; break; case '\n': escch = 'n'; break;
case '\v': escch = 'v'; break; case '\v': escch = 'v'; break;
case '\f': escch = 'f'; break; case '\f': escch = 'f'; break;
case '\r': escch = 'r'; break; case '\r': escch = 'r'; break;
case '\\': escch = '\\'; break; case '\\': escch = '\\'; break;
case '\"': escch = '\"'; break; case '\"': escch = '\"'; break;
case '\'': escch = '\''; break; case '\'': escch = '\''; break;
case 0: escch = '0'; break; case 0: escch = '0'; break;
} }
if(escch) { if(escch) {
*dest++ = '\\'; *dest++ = '\\';
*dest++ = escch; *dest++ = escch;
escaped++; escaped++;
} }
else { else {
*dest++ = c; *dest++ = c;
} }
} }
else { else {
dest += scsprintf(dest, destcharsize, escpat, c); dest += scsprintf(dest, destcharsize, escpat, c);
escaped++; escaped++;
} }
} }
if(escaped) { if(escaped) {
sq_pushstring(v,resstr,dest - resstr); sq_pushstring(v,resstr,dest - resstr);
} }
else { else {
sq_push(v,2); //nothing escaped sq_push(v,2); //nothing escaped
} }
return 1; return 1;
} }
static SQInteger _string_startswith(HRABBITVM v) static SQInteger _string_startswith(HRABBITVM v)
{ {
const SQChar *str,*cmp; const SQChar *str,*cmp;
sq_getstring(v,2,&str); sq_getstring(v,2,&str);
sq_getstring(v,3,&cmp); sq_getstring(v,3,&cmp);
SQInteger len = sq_getsize(v,2); SQInteger len = sq_getsize(v,2);
SQInteger cmplen = sq_getsize(v,3); SQInteger cmplen = sq_getsize(v,3);
SQBool ret = SQFalse; SQBool ret = SQFalse;
if(cmplen <= len) { if(cmplen <= len) {
ret = memcmp(str,cmp,sq_rsl(cmplen)) == 0 ? SQTrue : SQFalse; ret = memcmp(str,cmp,sq_rsl(cmplen)) == 0 ? SQTrue : SQFalse;
} }
sq_pushbool(v,ret); sq_pushbool(v,ret);
return 1; return 1;
} }
static SQInteger _string_endswith(HRABBITVM v) static SQInteger _string_endswith(HRABBITVM v)
{ {
const SQChar *str,*cmp; const SQChar *str,*cmp;
sq_getstring(v,2,&str); sq_getstring(v,2,&str);
sq_getstring(v,3,&cmp); sq_getstring(v,3,&cmp);
SQInteger len = sq_getsize(v,2); SQInteger len = sq_getsize(v,2);
SQInteger cmplen = sq_getsize(v,3); SQInteger cmplen = sq_getsize(v,3);
SQBool ret = SQFalse; SQBool ret = SQFalse;
if(cmplen <= len) { if(cmplen <= len) {
ret = memcmp(&str[len - cmplen],cmp,sq_rsl(cmplen)) == 0 ? SQTrue : SQFalse; ret = memcmp(&str[len - cmplen],cmp,sq_rsl(cmplen)) == 0 ? SQTrue : SQFalse;
} }
sq_pushbool(v,ret); sq_pushbool(v,ret);
return 1; return 1;
} }
#define SETUP_REX(v) \ #define SETUP_REX(v) \
SQRex *self = NULL; \ SQRex *self = NULL; \
sq_getinstanceup(v,1,(SQUserPointer *)&self,0); sq_getinstanceup(v,1,(SQUserPointer *)&self,0);
static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger SQ_UNUSED_ARG(size)) static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger SQ_UNUSED_ARG(size))
{ {
SQRex *self = ((SQRex *)p); SQRex *self = ((SQRex *)p);
sqstd_rex_free(self); sqstd_rex_free(self);
return 1; return 1;
} }
static SQInteger _regexp_match(HRABBITVM v) static SQInteger _regexp_match(HRABBITVM v)
{ {
SETUP_REX(v); SETUP_REX(v);
const SQChar *str; const SQChar *str;
sq_getstring(v,2,&str); sq_getstring(v,2,&str);
if(sqstd_rex_match(self,str) == SQTrue) if(sqstd_rex_match(self,str) == SQTrue)
{ {
sq_pushbool(v,SQTrue); sq_pushbool(v,SQTrue);
return 1; return 1;
} }
sq_pushbool(v,SQFalse); sq_pushbool(v,SQFalse);
return 1; return 1;
} }
static void _addrexmatch(HRABBITVM v,const SQChar *str,const SQChar *begin,const SQChar *end) static void _addrexmatch(HRABBITVM v,const SQChar *str,const SQChar *begin,const SQChar *end)
{ {
sq_newtable(v); sq_newtable(v);
sq_pushstring(v,_SC("begin"),-1); sq_pushstring(v,_SC("begin"),-1);
sq_pushinteger(v,begin - str); sq_pushinteger(v,begin - str);
sq_rawset(v,-3); sq_rawset(v,-3);
sq_pushstring(v,_SC("end"),-1); sq_pushstring(v,_SC("end"),-1);
sq_pushinteger(v,end - str); sq_pushinteger(v,end - str);
sq_rawset(v,-3); sq_rawset(v,-3);
} }
static SQInteger _regexp_search(HRABBITVM v) static SQInteger _regexp_search(HRABBITVM v)
{ {
SETUP_REX(v); SETUP_REX(v);
const SQChar *str,*begin,*end; const SQChar *str,*begin,*end;
SQInteger start = 0; SQInteger start = 0;
sq_getstring(v,2,&str); sq_getstring(v,2,&str);
if(sq_gettop(v) > 2) sq_getinteger(v,3,&start); if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) { if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
_addrexmatch(v,str,begin,end); _addrexmatch(v,str,begin,end);
return 1; return 1;
} }
return 0; return 0;
} }
static SQInteger _regexp_capture(HRABBITVM v) static SQInteger _regexp_capture(HRABBITVM v)
{ {
SETUP_REX(v); SETUP_REX(v);
const SQChar *str,*begin,*end; const SQChar *str,*begin,*end;
SQInteger start = 0; SQInteger start = 0;
sq_getstring(v,2,&str); sq_getstring(v,2,&str);
if(sq_gettop(v) > 2) sq_getinteger(v,3,&start); if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) { if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
SQInteger n = sqstd_rex_getsubexpcount(self); SQInteger n = sqstd_rex_getsubexpcount(self);
SQRexMatch match; SQRexMatch match;
sq_newarray(v,0); sq_newarray(v,0);
for(SQInteger i = 0;i < n; i++) { for(SQInteger i = 0;i < n; i++) {
sqstd_rex_getsubexp(self,i,&match); sqstd_rex_getsubexp(self,i,&match);
if(match.len > 0) if(match.len > 0)
_addrexmatch(v,str,match.begin,match.begin+match.len); _addrexmatch(v,str,match.begin,match.begin+match.len);
else else
_addrexmatch(v,str,str,str); //empty match _addrexmatch(v,str,str,str); //empty match
sq_arrayappend(v,-2); sq_arrayappend(v,-2);
} }
return 1; return 1;
} }
return 0; return 0;
} }
static SQInteger _regexp_subexpcount(HRABBITVM v) static SQInteger _regexp_subexpcount(HRABBITVM v)
{ {
SETUP_REX(v); SETUP_REX(v);
sq_pushinteger(v,sqstd_rex_getsubexpcount(self)); sq_pushinteger(v,sqstd_rex_getsubexpcount(self));
return 1; return 1;
} }
static SQInteger _regexp_constructor(HRABBITVM v) static SQInteger _regexp_constructor(HRABBITVM v)
{ {
const SQChar *error,*pattern; const SQChar *error,*pattern;
sq_getstring(v,2,&pattern); sq_getstring(v,2,&pattern);
SQRex *rex = sqstd_rex_compile(pattern,&error); SQRex *rex = sqstd_rex_compile(pattern,&error);
if(!rex) return sq_throwerror(v,error); if(!rex) return sq_throwerror(v,error);
sq_setinstanceup(v,1,rex); sq_setinstanceup(v,1,rex);
sq_setreleasehook(v,1,_rexobj_releasehook); sq_setreleasehook(v,1,_rexobj_releasehook);
return 0; return 0;
} }
static SQInteger _regexp__typeof(HRABBITVM v) static SQInteger _regexp__typeof(HRABBITVM v)
{ {
sq_pushstring(v,_SC("regexp"),-1); sq_pushstring(v,_SC("regexp"),-1);
return 1; return 1;
} }
#define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask} #define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask}
static const SQRegFunction rexobj_funcs[]={ static const SQRegFunction rexobj_funcs[]={
_DECL_REX_FUNC(constructor,2,_SC(".s")), _DECL_REX_FUNC(constructor,2,_SC(".s")),
_DECL_REX_FUNC(search,-2,_SC("xsn")), _DECL_REX_FUNC(search,-2,_SC("xsn")),
_DECL_REX_FUNC(match,2,_SC("xs")), _DECL_REX_FUNC(match,2,_SC("xs")),
_DECL_REX_FUNC(capture,-2,_SC("xsn")), _DECL_REX_FUNC(capture,-2,_SC("xsn")),
_DECL_REX_FUNC(subexpcount,1,_SC("x")), _DECL_REX_FUNC(subexpcount,1,_SC("x")),
_DECL_REX_FUNC(_typeof,1,_SC("x")), _DECL_REX_FUNC(_typeof,1,_SC("x")),
{NULL,(SQFUNCTION)0,0,NULL} {NULL,(SQFUNCTION)0,0,NULL}
}; };
#undef _DECL_REX_FUNC #undef _DECL_REX_FUNC
#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask} #define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask}
static const SQRegFunction stringlib_funcs[]={ static const SQRegFunction stringlib_funcs[]={
_DECL_FUNC(format,-2,_SC(".s")), _DECL_FUNC(format,-2,_SC(".s")),
_DECL_FUNC(printf,-2,_SC(".s")), _DECL_FUNC(printf,-2,_SC(".s")),
_DECL_FUNC(strip,2,_SC(".s")), _DECL_FUNC(strip,2,_SC(".s")),
_DECL_FUNC(lstrip,2,_SC(".s")), _DECL_FUNC(lstrip,2,_SC(".s")),
_DECL_FUNC(rstrip,2,_SC(".s")), _DECL_FUNC(rstrip,2,_SC(".s")),
_DECL_FUNC(split,3,_SC(".ss")), _DECL_FUNC(split,3,_SC(".ss")),
_DECL_FUNC(escape,2,_SC(".s")), _DECL_FUNC(escape,2,_SC(".s")),
_DECL_FUNC(startswith,3,_SC(".ss")), _DECL_FUNC(startswith,3,_SC(".ss")),
_DECL_FUNC(endswith,3,_SC(".ss")), _DECL_FUNC(endswith,3,_SC(".ss")),
{NULL,(SQFUNCTION)0,0,NULL} {NULL,(SQFUNCTION)0,0,NULL}
}; };
#undef _DECL_FUNC #undef _DECL_FUNC
SQInteger sqstd_register_stringlib(HRABBITVM v) SQInteger sqstd_register_stringlib(HRABBITVM v)
{ {
sq_pushstring(v,_SC("regexp"),-1); sq_pushstring(v,_SC("regexp"),-1);
sq_newclass(v,SQFalse); sq_newclass(v,SQFalse);
SQInteger i = 0; SQInteger i = 0;
while(rexobj_funcs[i].name != 0) { while(rexobj_funcs[i].name != 0) {
const SQRegFunction &f = rexobj_funcs[i]; const SQRegFunction &f = rexobj_funcs[i];
sq_pushstring(v,f.name,-1); sq_pushstring(v,f.name,-1);
sq_newclosure(v,f.f,0); sq_newclosure(v,f.f,0);
sq_setparamscheck(v,f.nparamscheck,f.typemask); sq_setparamscheck(v,f.nparamscheck,f.typemask);
sq_setnativeclosurename(v,-1,f.name); sq_setnativeclosurename(v,-1,f.name);
sq_newslot(v,-3,SQFalse); sq_newslot(v,-3,SQFalse);
i++; i++;
} }
sq_newslot(v,-3,SQFalse); sq_newslot(v,-3,SQFalse);
i = 0; i = 0;
while(stringlib_funcs[i].name!=0) while(stringlib_funcs[i].name!=0)
{ {
sq_pushstring(v,stringlib_funcs[i].name,-1); sq_pushstring(v,stringlib_funcs[i].name,-1);
sq_newclosure(v,stringlib_funcs[i].f,0); sq_newclosure(v,stringlib_funcs[i].f,0);
sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask); sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask);
sq_setnativeclosurename(v,-1,stringlib_funcs[i].name); sq_setnativeclosurename(v,-1,stringlib_funcs[i].name);
sq_newslot(v,-3,SQFalse); sq_newslot(v,-3,SQFalse);
i++; i++;
} }
return 1; return 1;
} }

View File

@ -11,8 +11,8 @@ typedef unsigned int SQRexBool;
typedef struct SQRex SQRex; typedef struct SQRex SQRex;
typedef struct { typedef struct {
const SQChar *begin; const SQChar *begin;
SQInteger len; SQInteger len;
} SQRexMatch; } SQRexMatch;
RABBIT_API SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error); RABBIT_API SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error);

View File

@ -29,125 +29,125 @@
static SQInteger _system_getenv(HRABBITVM v) static SQInteger _system_getenv(HRABBITVM v)
{ {
const SQChar *s; const SQChar *s;
if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){ if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
sq_pushstring(v,scgetenv(s),-1); sq_pushstring(v,scgetenv(s),-1);
return 1; return 1;
} }
return 0; return 0;
} }
static SQInteger _system_system(HRABBITVM v) static SQInteger _system_system(HRABBITVM v)
{ {
const SQChar *s; const SQChar *s;
if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){ if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
sq_pushinteger(v,scsystem(s)); sq_pushinteger(v,scsystem(s));
return 1; return 1;
} }
return sq_throwerror(v,_SC("wrong param")); return sq_throwerror(v,_SC("wrong param"));
} }
static SQInteger _system_clock(HRABBITVM v) static SQInteger _system_clock(HRABBITVM v)
{ {
sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC); sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC);
return 1; return 1;
} }
static SQInteger _system_time(HRABBITVM v) static SQInteger _system_time(HRABBITVM v)
{ {
SQInteger t = (SQInteger)time(NULL); SQInteger t = (SQInteger)time(NULL);
sq_pushinteger(v,t); sq_pushinteger(v,t);
return 1; return 1;
} }
static SQInteger _system_remove(HRABBITVM v) static SQInteger _system_remove(HRABBITVM v)
{ {
const SQChar *s; const SQChar *s;
sq_getstring(v,2,&s); sq_getstring(v,2,&s);
if(scremove(s)==-1) if(scremove(s)==-1)
return sq_throwerror(v,_SC("remove() failed")); return sq_throwerror(v,_SC("remove() failed"));
return 0; return 0;
} }
static SQInteger _system_rename(HRABBITVM v) static SQInteger _system_rename(HRABBITVM v)
{ {
const SQChar *oldn,*newn; const SQChar *oldn,*newn;
sq_getstring(v,2,&oldn); sq_getstring(v,2,&oldn);
sq_getstring(v,3,&newn); sq_getstring(v,3,&newn);
if(screname(oldn,newn)==-1) if(screname(oldn,newn)==-1)
return sq_throwerror(v,_SC("rename() failed")); return sq_throwerror(v,_SC("rename() failed"));
return 0; return 0;
} }
static void _set_integer_slot(HRABBITVM v,const SQChar *name,SQInteger val) static void _set_integer_slot(HRABBITVM v,const SQChar *name,SQInteger val)
{ {
sq_pushstring(v,name,-1); sq_pushstring(v,name,-1);
sq_pushinteger(v,val); sq_pushinteger(v,val);
sq_rawset(v,-3); sq_rawset(v,-3);
} }
static SQInteger _system_date(HRABBITVM v) static SQInteger _system_date(HRABBITVM v)
{ {
time_t t; time_t t;
SQInteger it; SQInteger it;
SQInteger format = 'l'; SQInteger format = 'l';
if(sq_gettop(v) > 1) { if(sq_gettop(v) > 1) {
sq_getinteger(v,2,&it); sq_getinteger(v,2,&it);
t = it; t = it;
if(sq_gettop(v) > 2) { if(sq_gettop(v) > 2) {
sq_getinteger(v,3,(SQInteger*)&format); sq_getinteger(v,3,(SQInteger*)&format);
} }
} }
else { else {
time(&t); time(&t);
} }
tm *date; tm *date;
if(format == 'u') if(format == 'u')
date = gmtime(&t); date = gmtime(&t);
else else
date = localtime(&t); date = localtime(&t);
if(!date) if(!date)
return sq_throwerror(v,_SC("crt api failure")); return sq_throwerror(v,_SC("crt api failure"));
sq_newtable(v); sq_newtable(v);
_set_integer_slot(v, _SC("sec"), date->tm_sec); _set_integer_slot(v, _SC("sec"), date->tm_sec);
_set_integer_slot(v, _SC("min"), date->tm_min); _set_integer_slot(v, _SC("min"), date->tm_min);
_set_integer_slot(v, _SC("hour"), date->tm_hour); _set_integer_slot(v, _SC("hour"), date->tm_hour);
_set_integer_slot(v, _SC("day"), date->tm_mday); _set_integer_slot(v, _SC("day"), date->tm_mday);
_set_integer_slot(v, _SC("month"), date->tm_mon); _set_integer_slot(v, _SC("month"), date->tm_mon);
_set_integer_slot(v, _SC("year"), date->tm_year+1900); _set_integer_slot(v, _SC("year"), date->tm_year+1900);
_set_integer_slot(v, _SC("wday"), date->tm_wday); _set_integer_slot(v, _SC("wday"), date->tm_wday);
_set_integer_slot(v, _SC("yday"), date->tm_yday); _set_integer_slot(v, _SC("yday"), date->tm_yday);
return 1; return 1;
} }
#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask} #define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask}
static const SQRegFunction systemlib_funcs[]={ static const SQRegFunction systemlib_funcs[]={
_DECL_FUNC(getenv,2,_SC(".s")), _DECL_FUNC(getenv,2,_SC(".s")),
_DECL_FUNC(system,2,_SC(".s")), _DECL_FUNC(system,2,_SC(".s")),
_DECL_FUNC(clock,0,NULL), _DECL_FUNC(clock,0,NULL),
_DECL_FUNC(time,1,NULL), _DECL_FUNC(time,1,NULL),
_DECL_FUNC(date,-1,_SC(".nn")), _DECL_FUNC(date,-1,_SC(".nn")),
_DECL_FUNC(remove,2,_SC(".s")), _DECL_FUNC(remove,2,_SC(".s")),
_DECL_FUNC(rename,3,_SC(".ss")), _DECL_FUNC(rename,3,_SC(".ss")),
{NULL,(SQFUNCTION)0,0,NULL} {NULL,(SQFUNCTION)0,0,NULL}
}; };
#undef _DECL_FUNC #undef _DECL_FUNC
SQInteger sqstd_register_systemlib(HRABBITVM v) SQInteger sqstd_register_systemlib(HRABBITVM v)
{ {
SQInteger i=0; SQInteger i=0;
while(systemlib_funcs[i].name!=0) while(systemlib_funcs[i].name!=0)
{ {
sq_pushstring(v,systemlib_funcs[i].name,-1); sq_pushstring(v,systemlib_funcs[i].name,-1);
sq_newclosure(v,systemlib_funcs[i].f,0); sq_newclosure(v,systemlib_funcs[i].f,0);
sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask); sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask);
sq_setnativeclosurename(v,-1,systemlib_funcs[i].name); sq_setnativeclosurename(v,-1,systemlib_funcs[i].name);
sq_newslot(v,-3,SQFalse); sq_newslot(v,-3,SQFalse);
i++; i++;
} }
return 1; return 1;
} }

View File

@ -50,66 +50,66 @@ struct SQOuter;
#include "sqconfig.hpp" #include "sqconfig.hpp"
#define RABBIT_VERSION _SC("Rabbit 0.1 un-stable") #define RABBIT_VERSION _SC("Rabbit 0.1 un-stable")
#define RABBIT_COPYRIGHT _SC("Copyright (C) 2003-2017 Alberto Demichelis") #define RABBIT_COPYRIGHT _SC("Copyright (C) 2003-2017 Alberto Demichelis")
#define RABBIT_AUTHOR _SC("Edouard DUPIN") #define RABBIT_AUTHOR _SC("Edouard DUPIN")
#define RABBIT_VERSION_NUMBER 010 #define RABBIT_VERSION_NUMBER 010
#define SQ_VMSTATE_IDLE 0 #define SQ_VMSTATE_IDLE 0
#define SQ_VMSTATE_RUNNING 1 #define SQ_VMSTATE_RUNNING 1
#define SQ_VMSTATE_SUSPENDED 2 #define SQ_VMSTATE_SUSPENDED 2
#define RABBIT_EOB 0 #define RABBIT_EOB 0
#define SQ_BYTECODE_STREAM_TAG 0xFAFA #define SQ_BYTECODE_STREAM_TAG 0xFAFA
#define SQOBJECT_REF_COUNTED 0x08000000 #define SQOBJECT_REF_COUNTED 0x08000000
#define SQOBJECT_NUMERIC 0x04000000 #define SQOBJECT_NUMERIC 0x04000000
#define SQOBJECT_DELEGABLE 0x02000000 #define SQOBJECT_DELEGABLE 0x02000000
#define SQOBJECT_CANBEFALSE 0x01000000 #define SQOBJECT_CANBEFALSE 0x01000000
#define SQ_MATCHTYPEMASKSTRING (-99999) #define SQ_MATCHTYPEMASKSTRING (-99999)
#define _RT_MASK 0x00FFFFFF #define _RT_MASK 0x00FFFFFF
#define _RAW_TYPE(type) (type&_RT_MASK) #define _RAW_TYPE(type) (type&_RT_MASK)
#define _RT_NULL 0x00000001 #define _RT_NULL 0x00000001
#define _RT_INTEGER 0x00000002 #define _RT_INTEGER 0x00000002
#define _RT_FLOAT 0x00000004 #define _RT_FLOAT 0x00000004
#define _RT_BOOL 0x00000008 #define _RT_BOOL 0x00000008
#define _RT_STRING 0x00000010 #define _RT_STRING 0x00000010
#define _RT_TABLE 0x00000020 #define _RT_TABLE 0x00000020
#define _RT_ARRAY 0x00000040 #define _RT_ARRAY 0x00000040
#define _RT_USERDATA 0x00000080 #define _RT_USERDATA 0x00000080
#define _RT_CLOSURE 0x00000100 #define _RT_CLOSURE 0x00000100
#define _RT_NATIVECLOSURE 0x00000200 #define _RT_NATIVECLOSURE 0x00000200
#define _RT_GENERATOR 0x00000400 #define _RT_GENERATOR 0x00000400
#define _RT_USERPOINTER 0x00000800 #define _RT_USERPOINTER 0x00000800
#define _RT_THREAD 0x00001000 #define _RT_THREAD 0x00001000
#define _RT_FUNCPROTO 0x00002000 #define _RT_FUNCPROTO 0x00002000
#define _RT_CLASS 0x00004000 #define _RT_CLASS 0x00004000
#define _RT_INSTANCE 0x00008000 #define _RT_INSTANCE 0x00008000
#define _RT_WEAKREF 0x00010000 #define _RT_WEAKREF 0x00010000
#define _RT_OUTER 0x00020000 #define _RT_OUTER 0x00020000
typedef enum tagSQObjectType{ typedef enum tagSQObjectType{
OT_NULL = (_RT_NULL|SQOBJECT_CANBEFALSE), OT_NULL = (_RT_NULL|SQOBJECT_CANBEFALSE),
OT_INTEGER = (_RT_INTEGER|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE), OT_INTEGER = (_RT_INTEGER|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
OT_FLOAT = (_RT_FLOAT|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE), OT_FLOAT = (_RT_FLOAT|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
OT_BOOL = (_RT_BOOL|SQOBJECT_CANBEFALSE), OT_BOOL = (_RT_BOOL|SQOBJECT_CANBEFALSE),
OT_STRING = (_RT_STRING|SQOBJECT_REF_COUNTED), OT_STRING = (_RT_STRING|SQOBJECT_REF_COUNTED),
OT_TABLE = (_RT_TABLE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE), OT_TABLE = (_RT_TABLE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
OT_ARRAY = (_RT_ARRAY|SQOBJECT_REF_COUNTED), OT_ARRAY = (_RT_ARRAY|SQOBJECT_REF_COUNTED),
OT_USERDATA = (_RT_USERDATA|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE), OT_USERDATA = (_RT_USERDATA|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
OT_CLOSURE = (_RT_CLOSURE|SQOBJECT_REF_COUNTED), OT_CLOSURE = (_RT_CLOSURE|SQOBJECT_REF_COUNTED),
OT_NATIVECLOSURE = (_RT_NATIVECLOSURE|SQOBJECT_REF_COUNTED), OT_NATIVECLOSURE = (_RT_NATIVECLOSURE|SQOBJECT_REF_COUNTED),
OT_GENERATOR = (_RT_GENERATOR|SQOBJECT_REF_COUNTED), OT_GENERATOR = (_RT_GENERATOR|SQOBJECT_REF_COUNTED),
OT_USERPOINTER = _RT_USERPOINTER, OT_USERPOINTER = _RT_USERPOINTER,
OT_THREAD = (_RT_THREAD|SQOBJECT_REF_COUNTED) , OT_THREAD = (_RT_THREAD|SQOBJECT_REF_COUNTED) ,
OT_FUNCPROTO = (_RT_FUNCPROTO|SQOBJECT_REF_COUNTED), //internal usage only OT_FUNCPROTO = (_RT_FUNCPROTO|SQOBJECT_REF_COUNTED), //internal usage only
OT_CLASS = (_RT_CLASS|SQOBJECT_REF_COUNTED), OT_CLASS = (_RT_CLASS|SQOBJECT_REF_COUNTED),
OT_INSTANCE = (_RT_INSTANCE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE), OT_INSTANCE = (_RT_INSTANCE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
OT_WEAKREF = (_RT_WEAKREF|SQOBJECT_REF_COUNTED), OT_WEAKREF = (_RT_WEAKREF|SQOBJECT_REF_COUNTED),
OT_OUTER = (_RT_OUTER|SQOBJECT_REF_COUNTED) //internal usage only OT_OUTER = (_RT_OUTER|SQOBJECT_REF_COUNTED) //internal usage only
}SQObjectType; }SQObjectType;
#define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED) #define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED)
@ -117,43 +117,43 @@ typedef enum tagSQObjectType{
typedef union tagSQObjectValue typedef union tagSQObjectValue
{ {
struct SQTable *pTable; struct SQTable *pTable;
struct SQArray *pArray; struct SQArray *pArray;
struct SQClosure *pClosure; struct SQClosure *pClosure;
struct SQOuter *pOuter; struct SQOuter *pOuter;
struct SQGenerator *pGenerator; struct SQGenerator *pGenerator;
struct SQNativeClosure *pNativeClosure; struct SQNativeClosure *pNativeClosure;
struct SQString *pString; struct SQString *pString;
struct SQUserData *pUserData; struct SQUserData *pUserData;
SQInteger nInteger; SQInteger nInteger;
SQFloat fFloat; SQFloat fFloat;
SQUserPointer pUserPointer; SQUserPointer pUserPointer;
struct SQFunctionProto *pFunctionProto; struct SQFunctionProto *pFunctionProto;
struct SQRefCounted *pRefCounted; struct SQRefCounted *pRefCounted;
struct SQDelegable *pDelegable; struct SQDelegable *pDelegable;
struct SQVM *pThread; struct SQVM *pThread;
struct SQClass *pClass; struct SQClass *pClass;
struct SQInstance *pInstance; struct SQInstance *pInstance;
struct SQWeakRef *pWeakRef; struct SQWeakRef *pWeakRef;
SQRawObjectVal raw; SQRawObjectVal raw;
}SQObjectValue; }SQObjectValue;
typedef struct tagSQObject typedef struct tagSQObject
{ {
SQObjectType _type; SQObjectType _type;
SQObjectValue _unVal; SQObjectValue _unVal;
}SQObject; }SQObject;
typedef struct tagSQMemberHandle{ typedef struct tagSQMemberHandle{
SQBool _static; SQBool _static;
SQInteger _index; SQInteger _index;
}SQMemberHandle; }SQMemberHandle;
typedef struct tagSQStackInfos{ typedef struct tagSQStackInfos{
const SQChar* funcname; const SQChar* funcname;
const SQChar* source; const SQChar* source;
SQInteger line; SQInteger line;
}SQStackInfos; }SQStackInfos;
typedef struct SQVM* HRABBITVM; typedef struct SQVM* HRABBITVM;
@ -170,17 +170,17 @@ typedef SQInteger (*SQREADFUNC)(SQUserPointer,SQUserPointer,SQInteger);
typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer); typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer);
typedef struct tagSQRegFunction{ typedef struct tagSQRegFunction{
const SQChar *name; const SQChar *name;
SQFUNCTION f; SQFUNCTION f;
SQInteger nparamscheck; SQInteger nparamscheck;
const SQChar *typemask; const SQChar *typemask;
}SQRegFunction; }SQRegFunction;
typedef struct tagSQFunctionInfo { typedef struct tagSQFunctionInfo {
SQUserPointer funcid; SQUserPointer funcid;
const SQChar *name; const SQChar *name;
const SQChar *source; const SQChar *source;
SQInteger line; SQInteger line;
}SQFunctionInfo; }SQFunctionInfo;
/*vm*/ /*vm*/

File diff suppressed because it is too large Load Diff

View File

@ -10,87 +10,87 @@
struct SQArray : public CHAINABLE_OBJ struct SQArray : public CHAINABLE_OBJ
{ {
private: private:
SQArray(SQSharedState *ss,SQInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);} SQArray(SQSharedState *ss,SQInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
~SQArray() ~SQArray()
{ {
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
} }
public: public:
static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){ static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){
SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray)); SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray));
new (newarray) SQArray(ss,nInitialSize); new (newarray) SQArray(ss,nInitialSize);
return newarray; return newarray;
} }
void Finalize(){ void Finalize(){
_values.resize(0); _values.resize(0);
} }
bool Get(const SQInteger nidx,SQObjectPtr &val) bool Get(const SQInteger nidx,SQObjectPtr &val)
{ {
if(nidx>=0 && nidx<(SQInteger)_values.size()){ if(nidx>=0 && nidx<(SQInteger)_values.size()){
SQObjectPtr &o = _values[nidx]; SQObjectPtr &o = _values[nidx];
val = _realval(o); val = _realval(o);
return true; return true;
} }
else return false; else return false;
} }
bool Set(const SQInteger nidx,const SQObjectPtr &val) bool Set(const SQInteger nidx,const SQObjectPtr &val)
{ {
if(nidx>=0 && nidx<(SQInteger)_values.size()){ if(nidx>=0 && nidx<(SQInteger)_values.size()){
_values[nidx]=val; _values[nidx]=val;
return true; return true;
} }
else return false; else return false;
} }
SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval) SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval)
{ {
SQUnsignedInteger idx=TranslateIndex(refpos); SQUnsignedInteger idx=TranslateIndex(refpos);
while(idx<_values.size()){ while(idx<_values.size()){
//first found //first found
outkey=(SQInteger)idx; outkey=(SQInteger)idx;
SQObjectPtr &o = _values[idx]; SQObjectPtr &o = _values[idx];
outval = _realval(o); outval = _realval(o);
//return idx for the next iteration //return idx for the next iteration
return ++idx; return ++idx;
} }
//nothing to iterate anymore //nothing to iterate anymore
return -1; return -1;
} }
SQArray *Clone(){SQArray *anew=Create(NULL,0); anew->_values.copy(_values); return anew; } SQArray *Clone(){SQArray *anew=Create(NULL,0); anew->_values.copy(_values); return anew; }
SQInteger Size() const {return _values.size();} SQInteger Size() const {return _values.size();}
void Resize(SQInteger size) void Resize(SQInteger size)
{ {
SQObjectPtr _null; SQObjectPtr _null;
Resize(size,_null); Resize(size,_null);
} }
void Resize(SQInteger size,SQObjectPtr &fill) { _values.resize(size,fill); ShrinkIfNeeded(); } void Resize(SQInteger size,SQObjectPtr &fill) { _values.resize(size,fill); ShrinkIfNeeded(); }
void Reserve(SQInteger size) { _values.reserve(size); } void Reserve(SQInteger size) { _values.reserve(size); }
void Append(const SQObject &o){_values.push_back(o);} void Append(const SQObject &o){_values.push_back(o);}
void Extend(const SQArray *a); void Extend(const SQArray *a);
SQObjectPtr &Top(){return _values.top();} SQObjectPtr &Top(){return _values.top();}
void Pop(){_values.pop_back(); ShrinkIfNeeded(); } void Pop(){_values.pop_back(); ShrinkIfNeeded(); }
bool Insert(SQInteger idx,const SQObject &val){ bool Insert(SQInteger idx,const SQObject &val){
if(idx < 0 || idx > (SQInteger)_values.size()) if(idx < 0 || idx > (SQInteger)_values.size())
return false; return false;
_values.insert(idx,val); _values.insert(idx,val);
return true; return true;
} }
void ShrinkIfNeeded() { void ShrinkIfNeeded() {
if(_values.size() <= _values.capacity()>>2) //shrink the array if(_values.size() <= _values.capacity()>>2) //shrink the array
_values.shrinktofit(); _values.shrinktofit();
} }
bool Remove(SQInteger idx){ bool Remove(SQInteger idx){
if(idx < 0 || idx >= (SQInteger)_values.size()) if(idx < 0 || idx >= (SQInteger)_values.size())
return false; return false;
_values.remove(idx); _values.remove(idx);
ShrinkIfNeeded(); ShrinkIfNeeded();
return true; return true;
} }
void Release() void Release()
{ {
sq_delete(this,SQArray); sq_delete(this,SQArray);
} }
SQObjectPtrVec _values; SQObjectPtrVec _values;
}; };

File diff suppressed because it is too large Load Diff

View File

@ -16,199 +16,199 @@
SQClass::SQClass(SQSharedState *ss,SQClass *base) SQClass::SQClass(SQSharedState *ss,SQClass *base)
{ {
_base = base; _base = base;
_typetag = 0; _typetag = 0;
_hook = NULL; _hook = NULL;
_udsize = 0; _udsize = 0;
_locked = false; _locked = false;
_constructoridx = -1; _constructoridx = -1;
if(_base) { if(_base) {
_constructoridx = _base->_constructoridx; _constructoridx = _base->_constructoridx;
_udsize = _base->_udsize; _udsize = _base->_udsize;
_defaultvalues.copy(base->_defaultvalues); _defaultvalues.copy(base->_defaultvalues);
_methods.copy(base->_methods); _methods.copy(base->_methods);
_COPY_VECTOR(_metamethods,base->_metamethods,MT_LAST); _COPY_VECTOR(_metamethods,base->_metamethods,MT_LAST);
__ObjAddRef(_base); __ObjAddRef(_base);
} }
_members = base?base->_members->Clone() : SQTable::Create(ss,0); _members = base?base->_members->Clone() : SQTable::Create(ss,0);
__ObjAddRef(_members); __ObjAddRef(_members);
INIT_CHAIN(); INIT_CHAIN();
ADD_TO_CHAIN(&_sharedstate->_gc_chain, this); ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
} }
void SQClass::Finalize() { void SQClass::Finalize() {
_attributes.Null(); _attributes.Null();
_NULL_SQOBJECT_VECTOR(_defaultvalues,_defaultvalues.size()); _NULL_SQOBJECT_VECTOR(_defaultvalues,_defaultvalues.size());
_methods.resize(0); _methods.resize(0);
_NULL_SQOBJECT_VECTOR(_metamethods,MT_LAST); _NULL_SQOBJECT_VECTOR(_metamethods,MT_LAST);
__ObjRelease(_members); __ObjRelease(_members);
if(_base) { if(_base) {
__ObjRelease(_base); __ObjRelease(_base);
} }
} }
SQClass::~SQClass() SQClass::~SQClass()
{ {
REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
Finalize(); Finalize();
} }
bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic) bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic)
{ {
SQObjectPtr temp; SQObjectPtr temp;
bool belongs_to_static_table = sq_type(val) == OT_CLOSURE || sq_type(val) == OT_NATIVECLOSURE || bstatic; bool belongs_to_static_table = sq_type(val) == OT_CLOSURE || sq_type(val) == OT_NATIVECLOSURE || bstatic;
if(_locked && !belongs_to_static_table) if(_locked && !belongs_to_static_table)
return false; //the class already has an instance so cannot be modified return false; //the class already has an instance so cannot be modified
if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value
{ {
_defaultvalues[_member_idx(temp)].val = val; _defaultvalues[_member_idx(temp)].val = val;
return true; return true;
} }
if(belongs_to_static_table) { if(belongs_to_static_table) {
SQInteger mmidx; SQInteger mmidx;
if((sq_type(val) == OT_CLOSURE || sq_type(val) == OT_NATIVECLOSURE) && if((sq_type(val) == OT_CLOSURE || sq_type(val) == OT_NATIVECLOSURE) &&
(mmidx = ss->GetMetaMethodIdxByName(key)) != -1) { (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) {
_metamethods[mmidx] = val; _metamethods[mmidx] = val;
} }
else { else {
SQObjectPtr theval = val; SQObjectPtr theval = val;
if(_base && sq_type(val) == OT_CLOSURE) { if(_base && sq_type(val) == OT_CLOSURE) {
theval = _closure(val)->Clone(); theval = _closure(val)->Clone();
_closure(theval)->_base = _base; _closure(theval)->_base = _base;
__ObjAddRef(_base); //ref for the closure __ObjAddRef(_base); //ref for the closure
} }
if(sq_type(temp) == OT_NULL) { if(sq_type(temp) == OT_NULL) {
bool isconstructor; bool isconstructor;
SQVM::IsEqual(ss->_constructoridx, key, isconstructor); SQVM::IsEqual(ss->_constructoridx, key, isconstructor);
if(isconstructor) { if(isconstructor) {
_constructoridx = (SQInteger)_methods.size(); _constructoridx = (SQInteger)_methods.size();
} }
SQClassMember m; SQClassMember m;
m.val = theval; m.val = theval;
_members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size()))); _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size())));
_methods.push_back(m); _methods.push_back(m);
} }
else { else {
_methods[_member_idx(temp)].val = theval; _methods[_member_idx(temp)].val = theval;
} }
} }
return true; return true;
} }
SQClassMember m; SQClassMember m;
m.val = val; m.val = val;
_members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size()))); _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size())));
_defaultvalues.push_back(m); _defaultvalues.push_back(m);
return true; return true;
} }
SQInstance *SQClass::CreateInstance() SQInstance *SQClass::CreateInstance()
{ {
if(!_locked) Lock(); if(!_locked) Lock();
return SQInstance::Create(NULL,this); return SQInstance::Create(NULL,this);
} }
SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
{ {
SQObjectPtr oval; SQObjectPtr oval;
SQInteger idx = _members->Next(false,refpos,outkey,oval); SQInteger idx = _members->Next(false,refpos,outkey,oval);
if(idx != -1) { if(idx != -1) {
if(_ismethod(oval)) { if(_ismethod(oval)) {
outval = _methods[_member_idx(oval)].val; outval = _methods[_member_idx(oval)].val;
} }
else { else {
SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val; SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val;
outval = _realval(o); outval = _realval(o);
} }
} }
return idx; return idx;
} }
bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val) bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val)
{ {
SQObjectPtr idx; SQObjectPtr idx;
if(_members->Get(key,idx)) { if(_members->Get(key,idx)) {
if(_isfield(idx)) if(_isfield(idx))
_defaultvalues[_member_idx(idx)].attrs = val; _defaultvalues[_member_idx(idx)].attrs = val;
else else
_methods[_member_idx(idx)].attrs = val; _methods[_member_idx(idx)].attrs = val;
return true; return true;
} }
return false; return false;
} }
bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval) bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval)
{ {
SQObjectPtr idx; SQObjectPtr idx;
if(_members->Get(key,idx)) { if(_members->Get(key,idx)) {
outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs); outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs);
return true; return true;
} }
return false; return false;
} }
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
void SQInstance::Init(SQSharedState *ss) void SQInstance::Init(SQSharedState *ss)
{ {
_userpointer = NULL; _userpointer = NULL;
_hook = NULL; _hook = NULL;
__ObjAddRef(_class); __ObjAddRef(_class);
_delegate = _class->_members; _delegate = _class->_members;
INIT_CHAIN(); INIT_CHAIN();
ADD_TO_CHAIN(&_sharedstate->_gc_chain, this); ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
} }
SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize) SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize)
{ {
_memsize = memsize; _memsize = memsize;
_class = c; _class = c;
SQUnsignedInteger nvalues = _class->_defaultvalues.size(); SQUnsignedInteger nvalues = _class->_defaultvalues.size();
for(SQUnsignedInteger n = 0; n < nvalues; n++) { for(SQUnsignedInteger n = 0; n < nvalues; n++) {
new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val); new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val);
} }
Init(ss); Init(ss);
} }
SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize) SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize)
{ {
_memsize = memsize; _memsize = memsize;
_class = i->_class; _class = i->_class;
SQUnsignedInteger nvalues = _class->_defaultvalues.size(); SQUnsignedInteger nvalues = _class->_defaultvalues.size();
for(SQUnsignedInteger n = 0; n < nvalues; n++) { for(SQUnsignedInteger n = 0; n < nvalues; n++) {
new (&_values[n]) SQObjectPtr(i->_values[n]); new (&_values[n]) SQObjectPtr(i->_values[n]);
} }
Init(ss); Init(ss);
} }
void SQInstance::Finalize() void SQInstance::Finalize()
{ {
SQUnsignedInteger nvalues = _class->_defaultvalues.size(); SQUnsignedInteger nvalues = _class->_defaultvalues.size();
__ObjRelease(_class); __ObjRelease(_class);
_NULL_SQOBJECT_VECTOR(_values,nvalues); _NULL_SQOBJECT_VECTOR(_values,nvalues);
} }
SQInstance::~SQInstance() SQInstance::~SQInstance()
{ {
REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
if(_class){ Finalize(); } //if _class is null it was already finalized by the GC if(_class){ Finalize(); } //if _class is null it was already finalized by the GC
} }
bool SQInstance::GetMetaMethod(SQVM* SQ_UNUSED_ARG(v),SQMetaMethod mm,SQObjectPtr &res) bool SQInstance::GetMetaMethod(SQVM* SQ_UNUSED_ARG(v),SQMetaMethod mm,SQObjectPtr &res)
{ {
if(sq_type(_class->_metamethods[mm]) != OT_NULL) { if(sq_type(_class->_metamethods[mm]) != OT_NULL) {
res = _class->_metamethods[mm]; res = _class->_metamethods[mm];
return true; return true;
} }
return false; return false;
} }
bool SQInstance::InstanceOf(SQClass *trg) bool SQInstance::InstanceOf(SQClass *trg)
{ {
SQClass *parent = _class; SQClass *parent = _class;
while(parent != NULL) { while(parent != NULL) {
if(parent == trg) if(parent == trg)
return true; return true;
parent = parent->_base; parent = parent->_base;
} }
return false; return false;
} }

View File

@ -10,12 +10,12 @@
struct SQInstance; struct SQInstance;
struct SQClassMember { struct SQClassMember {
SQObjectPtr val; SQObjectPtr val;
SQObjectPtr attrs; SQObjectPtr attrs;
void Null() { void Null() {
val.Null(); val.Null();
attrs.Null(); attrs.Null();
} }
}; };
typedef sqvector<SQClassMember> SQClassMemberVec; typedef sqvector<SQClassMember> SQClassMemberVec;
@ -32,127 +32,127 @@ typedef sqvector<SQClassMember> SQClassMemberVec;
struct SQClass : public CHAINABLE_OBJ struct SQClass : public CHAINABLE_OBJ
{ {
SQClass(SQSharedState *ss,SQClass *base); SQClass(SQSharedState *ss,SQClass *base);
public: public:
static SQClass* Create(SQSharedState *ss,SQClass *base) { static SQClass* Create(SQSharedState *ss,SQClass *base) {
SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass)); SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass));
new (newclass) SQClass(ss, base); new (newclass) SQClass(ss, base);
return newclass; return newclass;
} }
~SQClass(); ~SQClass();
bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic); bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic);
bool Get(const SQObjectPtr &key,SQObjectPtr &val) { bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
if(_members->Get(key,val)) { if(_members->Get(key,val)) {
if(_isfield(val)) { if(_isfield(val)) {
SQObjectPtr &o = _defaultvalues[_member_idx(val)].val; SQObjectPtr &o = _defaultvalues[_member_idx(val)].val;
val = _realval(o); val = _realval(o);
} }
else { else {
val = _methods[_member_idx(val)].val; val = _methods[_member_idx(val)].val;
} }
return true; return true;
} }
return false; return false;
} }
bool GetConstructor(SQObjectPtr &ctor) bool GetConstructor(SQObjectPtr &ctor)
{ {
if(_constructoridx != -1) { if(_constructoridx != -1) {
ctor = _methods[_constructoridx].val; ctor = _methods[_constructoridx].val;
return true; return true;
} }
return false; return false;
} }
bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val); bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val);
bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval); bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval);
void Lock() { _locked = true; if(_base) _base->Lock(); } void Lock() { _locked = true; if(_base) _base->Lock(); }
void Release() { void Release() {
if (_hook) { _hook(_typetag,0);} if (_hook) { _hook(_typetag,0);}
sq_delete(this, SQClass); sq_delete(this, SQClass);
} }
void Finalize(); void Finalize();
SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
SQInstance *CreateInstance(); SQInstance *CreateInstance();
SQTable *_members; SQTable *_members;
SQClass *_base; SQClass *_base;
SQClassMemberVec _defaultvalues; SQClassMemberVec _defaultvalues;
SQClassMemberVec _methods; SQClassMemberVec _methods;
SQObjectPtr _metamethods[MT_LAST]; SQObjectPtr _metamethods[MT_LAST];
SQObjectPtr _attributes; SQObjectPtr _attributes;
SQUserPointer _typetag; SQUserPointer _typetag;
SQRELEASEHOOK _hook; SQRELEASEHOOK _hook;
bool _locked; bool _locked;
SQInteger _constructoridx; SQInteger _constructoridx;
SQInteger _udsize; SQInteger _udsize;
}; };
#define calcinstancesize(_theclass_) \ #define calcinstancesize(_theclass_) \
(_theclass_->_udsize + sq_aligning(sizeof(SQInstance) + (sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0)))) (_theclass_->_udsize + sq_aligning(sizeof(SQInstance) + (sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0))))
struct SQInstance : public SQDelegable struct SQInstance : public SQDelegable
{ {
void Init(SQSharedState *ss); void Init(SQSharedState *ss);
SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize); SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize);
SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize); SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize);
public: public:
static SQInstance* Create(SQSharedState *ss,SQClass *theclass) { static SQInstance* Create(SQSharedState *ss,SQClass *theclass) {
SQInteger size = calcinstancesize(theclass); SQInteger size = calcinstancesize(theclass);
SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
new (newinst) SQInstance(ss, theclass,size); new (newinst) SQInstance(ss, theclass,size);
if(theclass->_udsize) { if(theclass->_udsize) {
newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize); newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize);
} }
return newinst; return newinst;
} }
SQInstance *Clone(SQSharedState *ss) SQInstance *Clone(SQSharedState *ss)
{ {
SQInteger size = calcinstancesize(_class); SQInteger size = calcinstancesize(_class);
SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
new (newinst) SQInstance(ss, this,size); new (newinst) SQInstance(ss, this,size);
if(_class->_udsize) { if(_class->_udsize) {
newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize); newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize);
} }
return newinst; return newinst;
} }
~SQInstance(); ~SQInstance();
bool Get(const SQObjectPtr &key,SQObjectPtr &val) { bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
if(_class->_members->Get(key,val)) { if(_class->_members->Get(key,val)) {
if(_isfield(val)) { if(_isfield(val)) {
SQObjectPtr &o = _values[_member_idx(val)]; SQObjectPtr &o = _values[_member_idx(val)];
val = _realval(o); val = _realval(o);
} }
else { else {
val = _class->_methods[_member_idx(val)].val; val = _class->_methods[_member_idx(val)].val;
} }
return true; return true;
} }
return false; return false;
} }
bool Set(const SQObjectPtr &key,const SQObjectPtr &val) { bool Set(const SQObjectPtr &key,const SQObjectPtr &val) {
SQObjectPtr idx; SQObjectPtr idx;
if(_class->_members->Get(key,idx) && _isfield(idx)) { if(_class->_members->Get(key,idx) && _isfield(idx)) {
_values[_member_idx(idx)] = val; _values[_member_idx(idx)] = val;
return true; return true;
} }
return false; return false;
} }
void Release() { void Release() {
_uiRef++; _uiRef++;
if (_hook) { _hook(_userpointer,0);} if (_hook) { _hook(_userpointer,0);}
_uiRef--; _uiRef--;
if(_uiRef > 0) return; if(_uiRef > 0) return;
SQInteger size = _memsize; SQInteger size = _memsize;
this->~SQInstance(); this->~SQInstance();
SQ_FREE(this, size); SQ_FREE(this, size);
} }
void Finalize(); void Finalize();
bool InstanceOf(SQClass *trg); bool InstanceOf(SQClass *trg);
bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res); bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
SQClass *_class; SQClass *_class;
SQUserPointer _userpointer; SQUserPointer _userpointer;
SQRELEASEHOOK _hook; SQRELEASEHOOK _hook;
SQInteger _memsize; SQInteger _memsize;
SQObjectPtr _values[1]; SQObjectPtr _values[1];
}; };

View File

@ -14,55 +14,55 @@ struct SQClass;
struct SQClosure : public CHAINABLE_OBJ struct SQClosure : public CHAINABLE_OBJ
{ {
private: private:
SQClosure(SQSharedState *ss,SQFunctionProto *func){_function = func; __ObjAddRef(_function); _base = NULL; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL; _root=NULL;} SQClosure(SQSharedState *ss,SQFunctionProto *func){_function = func; __ObjAddRef(_function); _base = NULL; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL; _root=NULL;}
public: public:
static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func,SQWeakRef *root){ static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func,SQWeakRef *root){
SQInteger size = _CALC_CLOSURE_SIZE(func); SQInteger size = _CALC_CLOSURE_SIZE(func);
SQClosure *nc=(SQClosure*)SQ_MALLOC(size); SQClosure *nc=(SQClosure*)SQ_MALLOC(size);
new (nc) SQClosure(ss,func); new (nc) SQClosure(ss,func);
nc->_outervalues = (SQObjectPtr *)(nc + 1); nc->_outervalues = (SQObjectPtr *)(nc + 1);
nc->_defaultparams = &nc->_outervalues[func->_noutervalues]; nc->_defaultparams = &nc->_outervalues[func->_noutervalues];
nc->_root = root; nc->_root = root;
__ObjAddRef(nc->_root); __ObjAddRef(nc->_root);
_CONSTRUCT_VECTOR(SQObjectPtr,func->_noutervalues,nc->_outervalues); _CONSTRUCT_VECTOR(SQObjectPtr,func->_noutervalues,nc->_outervalues);
_CONSTRUCT_VECTOR(SQObjectPtr,func->_ndefaultparams,nc->_defaultparams); _CONSTRUCT_VECTOR(SQObjectPtr,func->_ndefaultparams,nc->_defaultparams);
return nc; return nc;
} }
void Release(){ void Release(){
SQFunctionProto *f = _function; SQFunctionProto *f = _function;
SQInteger size = _CALC_CLOSURE_SIZE(f); SQInteger size = _CALC_CLOSURE_SIZE(f);
_DESTRUCT_VECTOR(SQObjectPtr,f->_noutervalues,_outervalues); _DESTRUCT_VECTOR(SQObjectPtr,f->_noutervalues,_outervalues);
_DESTRUCT_VECTOR(SQObjectPtr,f->_ndefaultparams,_defaultparams); _DESTRUCT_VECTOR(SQObjectPtr,f->_ndefaultparams,_defaultparams);
__ObjRelease(_function); __ObjRelease(_function);
this->~SQClosure(); this->~SQClosure();
sq_vm_free(this,size); sq_vm_free(this,size);
} }
void SetRoot(SQWeakRef *r) void SetRoot(SQWeakRef *r)
{ {
__ObjRelease(_root); __ObjRelease(_root);
_root = r; _root = r;
__ObjAddRef(_root); __ObjAddRef(_root);
} }
SQClosure *Clone() SQClosure *Clone()
{ {
SQFunctionProto *f = _function; SQFunctionProto *f = _function;
SQClosure * ret = SQClosure::Create(NULL,f,_root); SQClosure * ret = SQClosure::Create(NULL,f,_root);
ret->_env = _env; ret->_env = _env;
if(ret->_env) __ObjAddRef(ret->_env); if(ret->_env) __ObjAddRef(ret->_env);
_COPY_VECTOR(ret->_outervalues,_outervalues,f->_noutervalues); _COPY_VECTOR(ret->_outervalues,_outervalues,f->_noutervalues);
_COPY_VECTOR(ret->_defaultparams,_defaultparams,f->_ndefaultparams); _COPY_VECTOR(ret->_defaultparams,_defaultparams,f->_ndefaultparams);
return ret; return ret;
} }
~SQClosure(); ~SQClosure();
bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write); bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret); static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
SQWeakRef *_env; SQWeakRef *_env;
SQWeakRef *_root; SQWeakRef *_root;
SQClass *_base; SQClass *_base;
SQFunctionProto *_function; SQFunctionProto *_function;
SQObjectPtr *_outervalues; SQObjectPtr *_outervalues;
SQObjectPtr *_defaultparams; SQObjectPtr *_defaultparams;
}; };
////////////////////////////////////////////// //////////////////////////////////////////////
@ -70,60 +70,60 @@ struct SQOuter : public CHAINABLE_OBJ
{ {
private: private:
SQOuter(SQSharedState *ss, SQObjectPtr *outer){_valptr = outer; _next = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); } SQOuter(SQSharedState *ss, SQObjectPtr *outer){_valptr = outer; _next = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); }
public: public:
static SQOuter *Create(SQSharedState *ss, SQObjectPtr *outer) static SQOuter *Create(SQSharedState *ss, SQObjectPtr *outer)
{ {
SQOuter *nc = (SQOuter*)SQ_MALLOC(sizeof(SQOuter)); SQOuter *nc = (SQOuter*)SQ_MALLOC(sizeof(SQOuter));
new (nc) SQOuter(ss, outer); new (nc) SQOuter(ss, outer);
return nc; return nc;
} }
~SQOuter() { REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); } ~SQOuter() { REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); }
void Release() void Release()
{ {
this->~SQOuter(); this->~SQOuter();
sq_vm_free(this,sizeof(SQOuter)); sq_vm_free(this,sizeof(SQOuter));
} }
SQObjectPtr *_valptr; /* pointer to value on stack, or _value below */ SQObjectPtr *_valptr; /* pointer to value on stack, or _value below */
SQInteger _idx; /* idx in stack array, for relocation */ SQInteger _idx; /* idx in stack array, for relocation */
SQObjectPtr _value; /* value of outer after stack frame is closed */ SQObjectPtr _value; /* value of outer after stack frame is closed */
SQOuter *_next; /* pointer to next outer when frame is open */ SQOuter *_next; /* pointer to next outer when frame is open */
}; };
////////////////////////////////////////////// //////////////////////////////////////////////
struct SQGenerator : public CHAINABLE_OBJ struct SQGenerator : public CHAINABLE_OBJ
{ {
enum SQGeneratorState{eRunning,eSuspended,eDead}; enum SQGeneratorState{eRunning,eSuspended,eDead};
private: private:
SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);} SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
public: public:
static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){ static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){
SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator)); SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));
new (nc) SQGenerator(ss,closure); new (nc) SQGenerator(ss,closure);
return nc; return nc;
} }
~SQGenerator() ~SQGenerator()
{ {
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
} }
void Kill(){ void Kill(){
_state=eDead; _state=eDead;
_stack.resize(0); _stack.resize(0);
_closure.Null();} _closure.Null();}
void Release(){ void Release(){
sq_delete(this,SQGenerator); sq_delete(this,SQGenerator);
} }
bool Yield(SQVM *v,SQInteger target); bool Yield(SQVM *v,SQInteger target);
bool Resume(SQVM *v,SQObjectPtr &dest); bool Resume(SQVM *v,SQObjectPtr &dest);
SQObjectPtr _closure; SQObjectPtr _closure;
SQObjectPtrVec _stack; SQObjectPtrVec _stack;
SQVM::CallInfo _ci; SQVM::CallInfo _ci;
ExceptionsTraps _etraps; ExceptionsTraps _etraps;
SQGeneratorState _state; SQGeneratorState _state;
}; };
#define _CALC_NATVIVECLOSURE_SIZE(noutervalues) (sizeof(SQNativeClosure) + (noutervalues*sizeof(SQObjectPtr))) #define _CALC_NATVIVECLOSURE_SIZE(noutervalues) (sizeof(SQNativeClosure) + (noutervalues*sizeof(SQObjectPtr)))
@ -131,48 +131,48 @@ public:
struct SQNativeClosure : public CHAINABLE_OBJ struct SQNativeClosure : public CHAINABLE_OBJ
{ {
private: private:
SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;} SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;}
public: public:
static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func,SQInteger nouters) static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func,SQInteger nouters)
{ {
SQInteger size = _CALC_NATVIVECLOSURE_SIZE(nouters); SQInteger size = _CALC_NATVIVECLOSURE_SIZE(nouters);
SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(size); SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(size);
new (nc) SQNativeClosure(ss,func); new (nc) SQNativeClosure(ss,func);
nc->_outervalues = (SQObjectPtr *)(nc + 1); nc->_outervalues = (SQObjectPtr *)(nc + 1);
nc->_noutervalues = nouters; nc->_noutervalues = nouters;
_CONSTRUCT_VECTOR(SQObjectPtr,nc->_noutervalues,nc->_outervalues); _CONSTRUCT_VECTOR(SQObjectPtr,nc->_noutervalues,nc->_outervalues);
return nc; return nc;
} }
SQNativeClosure *Clone() SQNativeClosure *Clone()
{ {
SQNativeClosure * ret = SQNativeClosure::Create(NULL,_function,_noutervalues); SQNativeClosure * ret = SQNativeClosure::Create(NULL,_function,_noutervalues);
ret->_env = _env; ret->_env = _env;
if(ret->_env) __ObjAddRef(ret->_env); if(ret->_env) __ObjAddRef(ret->_env);
ret->_name = _name; ret->_name = _name;
_COPY_VECTOR(ret->_outervalues,_outervalues,_noutervalues); _COPY_VECTOR(ret->_outervalues,_outervalues,_noutervalues);
ret->_typecheck.copy(_typecheck); ret->_typecheck.copy(_typecheck);
ret->_nparamscheck = _nparamscheck; ret->_nparamscheck = _nparamscheck;
return ret; return ret;
} }
~SQNativeClosure() ~SQNativeClosure()
{ {
__ObjRelease(_env); __ObjRelease(_env);
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
} }
void Release(){ void Release(){
SQInteger size = _CALC_NATVIVECLOSURE_SIZE(_noutervalues); SQInteger size = _CALC_NATVIVECLOSURE_SIZE(_noutervalues);
_DESTRUCT_VECTOR(SQObjectPtr,_noutervalues,_outervalues); _DESTRUCT_VECTOR(SQObjectPtr,_noutervalues,_outervalues);
this->~SQNativeClosure(); this->~SQNativeClosure();
sq_free(this,size); sq_free(this,size);
} }
SQInteger _nparamscheck; SQInteger _nparamscheck;
SQIntVec _typecheck; SQIntVec _typecheck;
SQObjectPtr *_outervalues; SQObjectPtr *_outervalues;
SQUnsignedInteger _noutervalues; SQUnsignedInteger _noutervalues;
SQWeakRef *_env; SQWeakRef *_env;
SQFUNCTION _function; SQFUNCTION _function;
SQObjectPtr _name; SQObjectPtr _name;
}; };

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,7 @@ struct SQVM;
#define TK_IDENTIFIER 258 #define TK_IDENTIFIER 258
#define TK_STRING_LITERAL 259 #define TK_STRING_LITERAL 259
#define TK_INTEGER 260 #define TK_INTEGER 260
#define TK_FLOAT 261 #define TK_FLOAT 261
#define TK_BASE 262 #define TK_BASE 262
#define TK_DELETE 263 #define TK_DELETE 263
#define TK_EQ 264 #define TK_EQ 264
@ -20,13 +20,13 @@ struct SQVM;
#define TK_LE 266 #define TK_LE 266
#define TK_GE 267 #define TK_GE 267
#define TK_SWITCH 268 #define TK_SWITCH 268
#define TK_ARROW 269 #define TK_ARROW 269
#define TK_AND 270 #define TK_AND 270
#define TK_OR 271 #define TK_OR 271
#define TK_IF 272 #define TK_IF 272
#define TK_ELSE 273 #define TK_ELSE 273
#define TK_WHILE 274 #define TK_WHILE 274
#define TK_BREAK 275 #define TK_BREAK 275
#define TK_FOR 276 #define TK_FOR 276
#define TK_DO 277 #define TK_DO 277
#define TK_NULL 278 #define TK_NULL 278
@ -34,8 +34,8 @@ struct SQVM;
#define TK_IN 280 #define TK_IN 280
#define TK_NEWSLOT 281 #define TK_NEWSLOT 281
#define TK_MODULO 282 #define TK_MODULO 282
#define TK_LOCAL 283 #define TK_LOCAL 283
#define TK_CLONE 284 #define TK_CLONE 284
#define TK_FUNCTION 285 #define TK_FUNCTION 285
#define TK_RETURN 286 #define TK_RETURN 286
#define TK_TYPEOF 287 #define TK_TYPEOF 287

View File

@ -67,23 +67,23 @@ typedef SQInteger SQRESULT;
typedef wchar_t SQChar; typedef wchar_t SQChar;
#define scstrcmp wcscmp #define scstrcmp wcscmp
#ifdef _WIN32 #ifdef _WIN32
#define scsprintf _snwprintf #define scsprintf _snwprintf
#else #else
#define scsprintf swprintf #define scsprintf swprintf
#endif #endif
#define scstrlen wcslen #define scstrlen wcslen
#define scstrtod wcstod #define scstrtod wcstod
#ifdef _SQ64 #ifdef _SQ64
#define scstrtol wcstoll #define scstrtol wcstoll
#else #else
#define scstrtol wcstol #define scstrtol wcstol
#endif #endif
#define scstrtoul wcstoul #define scstrtoul wcstoul
#define scvsprintf vswprintf #define scvsprintf vswprintf
#define scstrstr wcsstr #define scstrstr wcsstr
#define scprintf wprintf #define scprintf wprintf
#ifdef _WIN32 #ifdef _WIN32
#define WCHAR_SIZE 2 #define WCHAR_SIZE 2
@ -112,26 +112,26 @@ typedef wchar_t SQChar;
#else #else
typedef char SQChar; typedef char SQChar;
#define _SC(a) a #define _SC(a) a
#define scstrcmp strcmp #define scstrcmp strcmp
#ifdef _MSC_VER #ifdef _MSC_VER
#define scsprintf _snprintf #define scsprintf _snprintf
#else #else
#define scsprintf snprintf #define scsprintf snprintf
#endif #endif
#define scstrlen strlen #define scstrlen strlen
#define scstrtod strtod #define scstrtod strtod
#ifdef _SQ64 #ifdef _SQ64
#ifdef _MSC_VER #ifdef _MSC_VER
#define scstrtol _strtoi64 #define scstrtol _strtoi64
#else #else
#define scstrtol strtoll #define scstrtol strtoll
#endif #endif
#else #else
#define scstrtol strtol #define scstrtol strtol
#endif #endif
#define scstrtoul strtoul #define scstrtoul strtoul
#define scvsprintf vsnprintf #define scvsprintf vsnprintf
#define scstrstr strstr #define scstrstr strstr
#define scisspace isspace #define scisspace isspace
#define scisdigit isdigit #define scisdigit isdigit
#define scisprint isprint #define scisprint isprint
@ -139,7 +139,7 @@ typedef char SQChar;
#define sciscntrl iscntrl #define sciscntrl iscntrl
#define scisalpha isalpha #define scisalpha isalpha
#define scisalnum isalnum #define scisalnum isalnum
#define scprintf printf #define scprintf printf
#define MAX_CHAR 0xFF #define MAX_CHAR 0xFF
#define sq_rsl(l) (l) #define sq_rsl(l) (l)

View File

@ -15,109 +15,109 @@
SQRESULT sq_getfunctioninfo(HRABBITVM v,SQInteger level,SQFunctionInfo *fi) SQRESULT sq_getfunctioninfo(HRABBITVM v,SQInteger level,SQFunctionInfo *fi)
{ {
SQInteger cssize = v->_callsstacksize; SQInteger cssize = v->_callsstacksize;
if (cssize > level) { if (cssize > level) {
SQVM::CallInfo &ci = v->_callsstack[cssize-level-1]; SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
if(sq_isclosure(ci._closure)) { if(sq_isclosure(ci._closure)) {
SQClosure *c = _closure(ci._closure); SQClosure *c = _closure(ci._closure);
SQFunctionProto *proto = c->_function; SQFunctionProto *proto = c->_function;
fi->funcid = proto; fi->funcid = proto;
fi->name = sq_type(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown"); fi->name = sq_type(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown");
fi->source = sq_type(proto->_sourcename) == OT_STRING?_stringval(proto->_sourcename):_SC("unknown"); fi->source = sq_type(proto->_sourcename) == OT_STRING?_stringval(proto->_sourcename):_SC("unknown");
fi->line = proto->_lineinfos[0]._line; fi->line = proto->_lineinfos[0]._line;
return SQ_OK; return SQ_OK;
} }
} }
return sq_throwerror(v,_SC("the object is not a closure")); return sq_throwerror(v,_SC("the object is not a closure"));
} }
SQRESULT sq_stackinfos(HRABBITVM v, SQInteger level, SQStackInfos *si) SQRESULT sq_stackinfos(HRABBITVM v, SQInteger level, SQStackInfos *si)
{ {
SQInteger cssize = v->_callsstacksize; SQInteger cssize = v->_callsstacksize;
if (cssize > level) { if (cssize > level) {
memset(si, 0, sizeof(SQStackInfos)); memset(si, 0, sizeof(SQStackInfos));
SQVM::CallInfo &ci = v->_callsstack[cssize-level-1]; SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
switch (sq_type(ci._closure)) { switch (sq_type(ci._closure)) {
case OT_CLOSURE:{ case OT_CLOSURE:{
SQFunctionProto *func = _closure(ci._closure)->_function; SQFunctionProto *func = _closure(ci._closure)->_function;
if (sq_type(func->_name) == OT_STRING) if (sq_type(func->_name) == OT_STRING)
si->funcname = _stringval(func->_name); si->funcname = _stringval(func->_name);
if (sq_type(func->_sourcename) == OT_STRING) if (sq_type(func->_sourcename) == OT_STRING)
si->source = _stringval(func->_sourcename); si->source = _stringval(func->_sourcename);
si->line = func->GetLine(ci._ip); si->line = func->GetLine(ci._ip);
} }
break; break;
case OT_NATIVECLOSURE: case OT_NATIVECLOSURE:
si->source = _SC("NATIVE"); si->source = _SC("NATIVE");
si->funcname = _SC("unknown"); si->funcname = _SC("unknown");
if(sq_type(_nativeclosure(ci._closure)->_name) == OT_STRING) if(sq_type(_nativeclosure(ci._closure)->_name) == OT_STRING)
si->funcname = _stringval(_nativeclosure(ci._closure)->_name); si->funcname = _stringval(_nativeclosure(ci._closure)->_name);
si->line = -1; si->line = -1;
break; break;
default: break; //shutup compiler default: break; //shutup compiler
} }
return SQ_OK; return SQ_OK;
} }
return SQ_ERROR; return SQ_ERROR;
} }
void SQVM::Raise_Error(const SQChar *s, ...) void SQVM::Raise_Error(const SQChar *s, ...)
{ {
va_list vl; va_list vl;
va_start(vl, s); va_start(vl, s);
SQInteger buffersize = (SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2); SQInteger buffersize = (SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2);
scvsprintf(_sp(sq_rsl(buffersize)),buffersize, s, vl); scvsprintf(_sp(sq_rsl(buffersize)),buffersize, s, vl);
va_end(vl); va_end(vl);
_lasterror = SQString::Create(_ss(this),_spval,-1); _lasterror = SQString::Create(_ss(this),_spval,-1);
} }
void SQVM::Raise_Error(const SQObjectPtr &desc) void SQVM::Raise_Error(const SQObjectPtr &desc)
{ {
_lasterror = desc; _lasterror = desc;
} }
SQString *SQVM::PrintObjVal(const SQObjectPtr &o) SQString *SQVM::PrintObjVal(const SQObjectPtr &o)
{ {
switch(sq_type(o)) { switch(sq_type(o)) {
case OT_STRING: return _string(o); case OT_STRING: return _string(o);
case OT_INTEGER: case OT_INTEGER:
scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)),sq_rsl(NUMBER_MAX_CHAR), _PRINT_INT_FMT, _integer(o)); scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)),sq_rsl(NUMBER_MAX_CHAR), _PRINT_INT_FMT, _integer(o));
return SQString::Create(_ss(this), _spval); return SQString::Create(_ss(this), _spval);
break; break;
case OT_FLOAT: case OT_FLOAT:
scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)), sq_rsl(NUMBER_MAX_CHAR), _SC("%.14g"), _float(o)); scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)), sq_rsl(NUMBER_MAX_CHAR), _SC("%.14g"), _float(o));
return SQString::Create(_ss(this), _spval); return SQString::Create(_ss(this), _spval);
break; break;
default: default:
return SQString::Create(_ss(this), GetTypeName(o)); return SQString::Create(_ss(this), GetTypeName(o));
} }
} }
void SQVM::Raise_IdxError(const SQObjectPtr &o) void SQVM::Raise_IdxError(const SQObjectPtr &o)
{ {
SQObjectPtr oval = PrintObjVal(o); SQObjectPtr oval = PrintObjVal(o);
Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval)); Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval));
} }
void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2) void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2)
{ {
SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2); SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2);
Raise_Error(_SC("comparison between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2)); Raise_Error(_SC("comparison between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2));
} }
void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type) void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type)
{ {
SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1); SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1);
SQInteger found = 0; SQInteger found = 0;
for(SQInteger i=0; i<16; i++) for(SQInteger i=0; i<16; i++)
{ {
SQInteger mask = ((SQInteger)1) << i; SQInteger mask = ((SQInteger)1) << i;
if(typemask & (mask)) { if(typemask & (mask)) {
if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes); if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes);
found ++; found ++;
StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes); StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes);
} }
} }
Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes)); Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes));
} }

View File

@ -10,45 +10,45 @@
#include <rabbit/sqopcodes.hpp> #include <rabbit/sqopcodes.hpp>
enum SQOuterType { enum SQOuterType {
otLOCAL = 0, otLOCAL = 0,
otOUTER = 1 otOUTER = 1
}; };
struct SQOuterVar struct SQOuterVar
{ {
SQOuterVar(){} SQOuterVar(){}
SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t) SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t)
{ {
_name = name; _name = name;
_src=src; _src=src;
_type=t; _type=t;
} }
SQOuterVar(const SQOuterVar &ov) SQOuterVar(const SQOuterVar &ov)
{ {
_type=ov._type; _type=ov._type;
_src=ov._src; _src=ov._src;
_name=ov._name; _name=ov._name;
} }
SQOuterType _type; SQOuterType _type;
SQObjectPtr _name; SQObjectPtr _name;
SQObjectPtr _src; SQObjectPtr _src;
}; };
struct SQLocalVarInfo struct SQLocalVarInfo
{ {
SQLocalVarInfo():_start_op(0),_end_op(0),_pos(0){} SQLocalVarInfo():_start_op(0),_end_op(0),_pos(0){}
SQLocalVarInfo(const SQLocalVarInfo &lvi) SQLocalVarInfo(const SQLocalVarInfo &lvi)
{ {
_name=lvi._name; _name=lvi._name;
_start_op=lvi._start_op; _start_op=lvi._start_op;
_end_op=lvi._end_op; _end_op=lvi._end_op;
_pos=lvi._pos; _pos=lvi._pos;
} }
SQObjectPtr _name; SQObjectPtr _name;
SQUnsignedInteger _start_op; SQUnsignedInteger _start_op;
SQUnsignedInteger _end_op; SQUnsignedInteger _end_op;
SQUnsignedInteger _pos; SQUnsignedInteger _pos;
}; };
struct SQLineInfo { SQInteger _line;SQInteger _op; }; struct SQLineInfo { SQInteger _line;SQInteger _op; };
@ -58,95 +58,95 @@ typedef sqvector<SQLocalVarInfo> SQLocalVarInfoVec;
typedef sqvector<SQLineInfo> SQLineInfoVec; typedef sqvector<SQLineInfo> SQLineInfoVec;
#define _FUNC_SIZE(ni,nl,nparams,nfuncs,nouters,nlineinf,localinf,defparams) (sizeof(SQFunctionProto) \ #define _FUNC_SIZE(ni,nl,nparams,nfuncs,nouters,nlineinf,localinf,defparams) (sizeof(SQFunctionProto) \
+((ni-1)*sizeof(SQInstruction))+(nl*sizeof(SQObjectPtr)) \ +((ni-1)*sizeof(SQInstruction))+(nl*sizeof(SQObjectPtr)) \
+(nparams*sizeof(SQObjectPtr))+(nfuncs*sizeof(SQObjectPtr)) \ +(nparams*sizeof(SQObjectPtr))+(nfuncs*sizeof(SQObjectPtr)) \
+(nouters*sizeof(SQOuterVar))+(nlineinf*sizeof(SQLineInfo)) \ +(nouters*sizeof(SQOuterVar))+(nlineinf*sizeof(SQLineInfo)) \
+(localinf*sizeof(SQLocalVarInfo))+(defparams*sizeof(SQInteger))) +(localinf*sizeof(SQLocalVarInfo))+(defparams*sizeof(SQInteger)))
struct SQFunctionProto : public CHAINABLE_OBJ struct SQFunctionProto : public CHAINABLE_OBJ
{ {
private: private:
SQFunctionProto(SQSharedState *ss); SQFunctionProto(SQSharedState *ss);
~SQFunctionProto(); ~SQFunctionProto();
public: public:
static SQFunctionProto *Create(SQSharedState *ss,SQInteger ninstructions, static SQFunctionProto *Create(SQSharedState *ss,SQInteger ninstructions,
SQInteger nliterals,SQInteger nparameters, SQInteger nliterals,SQInteger nparameters,
SQInteger nfunctions,SQInteger noutervalues, SQInteger nfunctions,SQInteger noutervalues,
SQInteger nlineinfos,SQInteger nlocalvarinfos,SQInteger ndefaultparams) SQInteger nlineinfos,SQInteger nlocalvarinfos,SQInteger ndefaultparams)
{ {
SQFunctionProto *f; SQFunctionProto *f;
//I compact the whole class and members in a single memory allocation //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)); f = (SQFunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams));
new (f) SQFunctionProto(ss); new (f) SQFunctionProto(ss);
f->_ninstructions = ninstructions; f->_ninstructions = ninstructions;
f->_literals = (SQObjectPtr*)&f->_instructions[ninstructions]; f->_literals = (SQObjectPtr*)&f->_instructions[ninstructions];
f->_nliterals = nliterals; f->_nliterals = nliterals;
f->_parameters = (SQObjectPtr*)&f->_literals[nliterals]; f->_parameters = (SQObjectPtr*)&f->_literals[nliterals];
f->_nparameters = nparameters; f->_nparameters = nparameters;
f->_functions = (SQObjectPtr*)&f->_parameters[nparameters]; f->_functions = (SQObjectPtr*)&f->_parameters[nparameters];
f->_nfunctions = nfunctions; f->_nfunctions = nfunctions;
f->_outervalues = (SQOuterVar*)&f->_functions[nfunctions]; f->_outervalues = (SQOuterVar*)&f->_functions[nfunctions];
f->_noutervalues = noutervalues; f->_noutervalues = noutervalues;
f->_lineinfos = (SQLineInfo *)&f->_outervalues[noutervalues]; f->_lineinfos = (SQLineInfo *)&f->_outervalues[noutervalues];
f->_nlineinfos = nlineinfos; f->_nlineinfos = nlineinfos;
f->_localvarinfos = (SQLocalVarInfo *)&f->_lineinfos[nlineinfos]; f->_localvarinfos = (SQLocalVarInfo *)&f->_lineinfos[nlineinfos];
f->_nlocalvarinfos = nlocalvarinfos; f->_nlocalvarinfos = nlocalvarinfos;
f->_defaultparams = (SQInteger *)&f->_localvarinfos[nlocalvarinfos]; f->_defaultparams = (SQInteger *)&f->_localvarinfos[nlocalvarinfos];
f->_ndefaultparams = ndefaultparams; f->_ndefaultparams = ndefaultparams;
_CONSTRUCT_VECTOR(SQObjectPtr,f->_nliterals,f->_literals); _CONSTRUCT_VECTOR(SQObjectPtr,f->_nliterals,f->_literals);
_CONSTRUCT_VECTOR(SQObjectPtr,f->_nparameters,f->_parameters); _CONSTRUCT_VECTOR(SQObjectPtr,f->_nparameters,f->_parameters);
_CONSTRUCT_VECTOR(SQObjectPtr,f->_nfunctions,f->_functions); _CONSTRUCT_VECTOR(SQObjectPtr,f->_nfunctions,f->_functions);
_CONSTRUCT_VECTOR(SQOuterVar,f->_noutervalues,f->_outervalues); _CONSTRUCT_VECTOR(SQOuterVar,f->_noutervalues,f->_outervalues);
//_CONSTRUCT_VECTOR(SQLineInfo,f->_nlineinfos,f->_lineinfos); //not required are 2 integers //_CONSTRUCT_VECTOR(SQLineInfo,f->_nlineinfos,f->_lineinfos); //not required are 2 integers
_CONSTRUCT_VECTOR(SQLocalVarInfo,f->_nlocalvarinfos,f->_localvarinfos); _CONSTRUCT_VECTOR(SQLocalVarInfo,f->_nlocalvarinfos,f->_localvarinfos);
return f; return f;
} }
void Release(){ void Release(){
_DESTRUCT_VECTOR(SQObjectPtr,_nliterals,_literals); _DESTRUCT_VECTOR(SQObjectPtr,_nliterals,_literals);
_DESTRUCT_VECTOR(SQObjectPtr,_nparameters,_parameters); _DESTRUCT_VECTOR(SQObjectPtr,_nparameters,_parameters);
_DESTRUCT_VECTOR(SQObjectPtr,_nfunctions,_functions); _DESTRUCT_VECTOR(SQObjectPtr,_nfunctions,_functions);
_DESTRUCT_VECTOR(SQOuterVar,_noutervalues,_outervalues); _DESTRUCT_VECTOR(SQOuterVar,_noutervalues,_outervalues);
//_DESTRUCT_VECTOR(SQLineInfo,_nlineinfos,_lineinfos); //not required are 2 integers //_DESTRUCT_VECTOR(SQLineInfo,_nlineinfos,_lineinfos); //not required are 2 integers
_DESTRUCT_VECTOR(SQLocalVarInfo,_nlocalvarinfos,_localvarinfos); _DESTRUCT_VECTOR(SQLocalVarInfo,_nlocalvarinfos,_localvarinfos);
SQInteger size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos,_ndefaultparams); SQInteger size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos,_ndefaultparams);
this->~SQFunctionProto(); this->~SQFunctionProto();
sq_vm_free(this,size); sq_vm_free(this,size);
} }
const SQChar* GetLocal(SQVM *v,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop); const SQChar* GetLocal(SQVM *v,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop);
SQInteger GetLine(SQInstruction *curr); SQInteger GetLine(SQInstruction *curr);
bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write); bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret); static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
SQObjectPtr _sourcename; SQObjectPtr _sourcename;
SQObjectPtr _name; SQObjectPtr _name;
SQInteger _stacksize; SQInteger _stacksize;
bool _bgenerator; bool _bgenerator;
SQInteger _varparams; SQInteger _varparams;
SQInteger _nlocalvarinfos; SQInteger _nlocalvarinfos;
SQLocalVarInfo *_localvarinfos; SQLocalVarInfo *_localvarinfos;
SQInteger _nlineinfos; SQInteger _nlineinfos;
SQLineInfo *_lineinfos; SQLineInfo *_lineinfos;
SQInteger _nliterals; SQInteger _nliterals;
SQObjectPtr *_literals; SQObjectPtr *_literals;
SQInteger _nparameters; SQInteger _nparameters;
SQObjectPtr *_parameters; SQObjectPtr *_parameters;
SQInteger _nfunctions; SQInteger _nfunctions;
SQObjectPtr *_functions; SQObjectPtr *_functions;
SQInteger _noutervalues; SQInteger _noutervalues;
SQOuterVar *_outervalues; SQOuterVar *_outervalues;
SQInteger _ndefaultparams; SQInteger _ndefaultparams;
SQInteger *_defaultparams; SQInteger *_defaultparams;
SQInteger _ninstructions; SQInteger _ninstructions;
SQInstruction _instructions[1]; SQInstruction _instructions[1];
}; };

File diff suppressed because it is too large Load Diff

View File

@ -11,84 +11,84 @@
struct SQFuncState struct SQFuncState
{ {
SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed); SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed);
~SQFuncState(); ~SQFuncState();
#ifdef _DEBUG_DUMP #ifdef _DEBUG_DUMP
void Dump(SQFunctionProto *func); void Dump(SQFunctionProto *func);
#endif #endif
void Error(const SQChar *err); void Error(const SQChar *err);
SQFuncState *PushChildState(SQSharedState *ss); SQFuncState *PushChildState(SQSharedState *ss);
void PopChildState(); void PopChildState();
void AddInstruction(SQOpcode _op,SQInteger arg0=0,SQInteger arg1=0,SQInteger arg2=0,SQInteger arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);} void AddInstruction(SQOpcode _op,SQInteger arg0=0,SQInteger arg1=0,SQInteger arg2=0,SQInteger arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);}
void AddInstruction(SQInstruction &i); void AddInstruction(SQInstruction &i);
void SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2=0,SQInteger arg3=0); void SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2=0,SQInteger arg3=0);
void SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val); void SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val);
SQInstruction &GetInstruction(SQInteger pos){return _instructions[pos];} SQInstruction &GetInstruction(SQInteger pos){return _instructions[pos];}
void PopInstructions(SQInteger size){for(SQInteger i=0;i<size;i++)_instructions.pop_back();} void PopInstructions(SQInteger size){for(SQInteger i=0;i<size;i++)_instructions.pop_back();}
void SetStackSize(SQInteger n); void SetStackSize(SQInteger n);
SQInteger CountOuters(SQInteger stacksize); SQInteger CountOuters(SQInteger stacksize);
void SnoozeOpt(){_optimization=false;} void SnoozeOpt(){_optimization=false;}
void AddDefaultParam(SQInteger trg) { _defaultparams.push_back(trg); } void AddDefaultParam(SQInteger trg) { _defaultparams.push_back(trg); }
SQInteger GetDefaultParamCount() { return _defaultparams.size(); } SQInteger GetDefaultParamCount() { return _defaultparams.size(); }
SQInteger GetCurrentPos(){return _instructions.size()-1;} SQInteger GetCurrentPos(){return _instructions.size()-1;}
SQInteger GetNumericConstant(const SQInteger cons); SQInteger GetNumericConstant(const SQInteger cons);
SQInteger GetNumericConstant(const SQFloat cons); SQInteger GetNumericConstant(const SQFloat cons);
SQInteger PushLocalVariable(const SQObject &name); SQInteger PushLocalVariable(const SQObject &name);
void AddParameter(const SQObject &name); void AddParameter(const SQObject &name);
//void AddOuterValue(const SQObject &name); //void AddOuterValue(const SQObject &name);
SQInteger GetLocalVariable(const SQObject &name); SQInteger GetLocalVariable(const SQObject &name);
void MarkLocalAsOuter(SQInteger pos); void MarkLocalAsOuter(SQInteger pos);
SQInteger GetOuterVariable(const SQObject &name); SQInteger GetOuterVariable(const SQObject &name);
SQInteger GenerateCode(); SQInteger GenerateCode();
SQInteger GetStackSize(); SQInteger GetStackSize();
SQInteger CalcStackFrameSize(); SQInteger CalcStackFrameSize();
void AddLineInfos(SQInteger line,bool lineop,bool force=false); void AddLineInfos(SQInteger line,bool lineop,bool force=false);
SQFunctionProto *BuildProto(); SQFunctionProto *BuildProto();
SQInteger AllocStackPos(); SQInteger AllocStackPos();
SQInteger PushTarget(SQInteger n=-1); SQInteger PushTarget(SQInteger n=-1);
SQInteger PopTarget(); SQInteger PopTarget();
SQInteger TopTarget(); SQInteger TopTarget();
SQInteger GetUpTarget(SQInteger n); SQInteger GetUpTarget(SQInteger n);
void DiscardTarget(); void DiscardTarget();
bool IsLocal(SQUnsignedInteger stkpos); bool IsLocal(SQUnsignedInteger stkpos);
SQObject CreateString(const SQChar *s,SQInteger len = -1); SQObject CreateString(const SQChar *s,SQInteger len = -1);
SQObject CreateTable(); SQObject CreateTable();
bool IsConstant(const SQObject &name,SQObject &e); bool IsConstant(const SQObject &name,SQObject &e);
SQInteger _returnexp; SQInteger _returnexp;
SQLocalVarInfoVec _vlocals; SQLocalVarInfoVec _vlocals;
SQIntVec _targetstack; SQIntVec _targetstack;
SQInteger _stacksize; SQInteger _stacksize;
bool _varparams; bool _varparams;
bool _bgenerator; bool _bgenerator;
SQIntVec _unresolvedbreaks; SQIntVec _unresolvedbreaks;
SQIntVec _unresolvedcontinues; SQIntVec _unresolvedcontinues;
SQObjectPtrVec _functions; SQObjectPtrVec _functions;
SQObjectPtrVec _parameters; SQObjectPtrVec _parameters;
SQOuterVarVec _outervalues; SQOuterVarVec _outervalues;
SQInstructionVec _instructions; SQInstructionVec _instructions;
SQLocalVarInfoVec _localvarinfos; SQLocalVarInfoVec _localvarinfos;
SQObjectPtr _literals; SQObjectPtr _literals;
SQObjectPtr _strings; SQObjectPtr _strings;
SQObjectPtr _name; SQObjectPtr _name;
SQObjectPtr _sourcename; SQObjectPtr _sourcename;
SQInteger _nliterals; SQInteger _nliterals;
SQLineInfoVec _lineinfos; SQLineInfoVec _lineinfos;
SQFuncState *_parent; SQFuncState *_parent;
SQIntVec _scope_blocks; SQIntVec _scope_blocks;
SQIntVec _breaktargets; SQIntVec _breaktargets;
SQIntVec _continuetargets; SQIntVec _continuetargets;
SQIntVec _defaultparams; SQIntVec _defaultparams;
SQInteger _lastline; SQInteger _lastline;
SQInteger _traps; //contains number of nested exception traps SQInteger _traps; //contains number of nested exception traps
SQInteger _outers; SQInteger _outers;
bool _optimization; bool _optimization;
SQSharedState *_sharedstate; SQSharedState *_sharedstate;
sqvector<SQFuncState*> _childstates; sqvector<SQFuncState*> _childstates;
SQInteger GetConstant(const SQObject &cons); SQInteger GetConstant(const SQObject &cons);
private: private:
CompilerErrorFunc _errfunc; CompilerErrorFunc _errfunc;
void *_errtarget; void *_errtarget;
SQSharedState *_ss; SQSharedState *_ss;
}; };

View File

@ -26,456 +26,456 @@
SQLexer::SQLexer(){} SQLexer::SQLexer(){}
SQLexer::~SQLexer() SQLexer::~SQLexer()
{ {
_keywords->Release(); _keywords->Release();
} }
void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed) void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed)
{ {
_errfunc = efunc; _errfunc = efunc;
_errtarget = ed; _errtarget = ed;
_sharedstate = ss; _sharedstate = ss;
_keywords = SQTable::Create(ss, 37); _keywords = SQTable::Create(ss, 37);
ADD_KEYWORD(while, TK_WHILE); ADD_KEYWORD(while, TK_WHILE);
ADD_KEYWORD(do, TK_DO); ADD_KEYWORD(do, TK_DO);
ADD_KEYWORD(if, TK_IF); ADD_KEYWORD(if, TK_IF);
ADD_KEYWORD(else, TK_ELSE); ADD_KEYWORD(else, TK_ELSE);
ADD_KEYWORD(break, TK_BREAK); ADD_KEYWORD(break, TK_BREAK);
ADD_KEYWORD(continue, TK_CONTINUE); ADD_KEYWORD(continue, TK_CONTINUE);
ADD_KEYWORD(return, TK_RETURN); ADD_KEYWORD(return, TK_RETURN);
ADD_KEYWORD(null, TK_NULL); ADD_KEYWORD(null, TK_NULL);
ADD_KEYWORD(function, TK_FUNCTION); ADD_KEYWORD(function, TK_FUNCTION);
ADD_KEYWORD(local, TK_LOCAL); ADD_KEYWORD(local, TK_LOCAL);
ADD_KEYWORD(for, TK_FOR); ADD_KEYWORD(for, TK_FOR);
ADD_KEYWORD(foreach, TK_FOREACH); ADD_KEYWORD(foreach, TK_FOREACH);
ADD_KEYWORD(in, TK_IN); ADD_KEYWORD(in, TK_IN);
ADD_KEYWORD(typeof, TK_TYPEOF); ADD_KEYWORD(typeof, TK_TYPEOF);
ADD_KEYWORD(base, TK_BASE); ADD_KEYWORD(base, TK_BASE);
ADD_KEYWORD(delete, TK_DELETE); ADD_KEYWORD(delete, TK_DELETE);
ADD_KEYWORD(try, TK_TRY); ADD_KEYWORD(try, TK_TRY);
ADD_KEYWORD(catch, TK_CATCH); ADD_KEYWORD(catch, TK_CATCH);
ADD_KEYWORD(throw, TK_THROW); ADD_KEYWORD(throw, TK_THROW);
ADD_KEYWORD(clone, TK_CLONE); ADD_KEYWORD(clone, TK_CLONE);
ADD_KEYWORD(yield, TK_YIELD); ADD_KEYWORD(yield, TK_YIELD);
ADD_KEYWORD(resume, TK_RESUME); ADD_KEYWORD(resume, TK_RESUME);
ADD_KEYWORD(switch, TK_SWITCH); ADD_KEYWORD(switch, TK_SWITCH);
ADD_KEYWORD(case, TK_CASE); ADD_KEYWORD(case, TK_CASE);
ADD_KEYWORD(default, TK_DEFAULT); ADD_KEYWORD(default, TK_DEFAULT);
ADD_KEYWORD(this, TK_THIS); ADD_KEYWORD(this, TK_THIS);
ADD_KEYWORD(class,TK_CLASS); ADD_KEYWORD(class,TK_CLASS);
ADD_KEYWORD(extends,TK_EXTENDS); ADD_KEYWORD(extends,TK_EXTENDS);
ADD_KEYWORD(constructor,TK_CONSTRUCTOR); ADD_KEYWORD(constructor,TK_CONSTRUCTOR);
ADD_KEYWORD(instanceof,TK_INSTANCEOF); ADD_KEYWORD(instanceof,TK_INSTANCEOF);
ADD_KEYWORD(true,TK_TRUE); ADD_KEYWORD(true,TK_TRUE);
ADD_KEYWORD(false,TK_FALSE); ADD_KEYWORD(false,TK_FALSE);
ADD_KEYWORD(static,TK_STATIC); ADD_KEYWORD(static,TK_STATIC);
ADD_KEYWORD(enum,TK_ENUM); ADD_KEYWORD(enum,TK_ENUM);
ADD_KEYWORD(const,TK_CONST); ADD_KEYWORD(const,TK_CONST);
ADD_KEYWORD(__LINE__,TK___LINE__); ADD_KEYWORD(__LINE__,TK___LINE__);
ADD_KEYWORD(__FILE__,TK___FILE__); ADD_KEYWORD(__FILE__,TK___FILE__);
ADD_KEYWORD(rawcall, TK_RAWCALL); ADD_KEYWORD(rawcall, TK_RAWCALL);
_readf = rg; _readf = rg;
_up = up; _up = up;
_lasttokenline = _currentline = 1; _lasttokenline = _currentline = 1;
_currentcolumn = 0; _currentcolumn = 0;
_prevtoken = -1; _prevtoken = -1;
_reached_eof = SQFalse; _reached_eof = SQFalse;
Next(); Next();
} }
void SQLexer::Error(const SQChar *err) void SQLexer::Error(const SQChar *err)
{ {
_errfunc(_errtarget,err); _errfunc(_errtarget,err);
} }
void SQLexer::Next() void SQLexer::Next()
{ {
SQInteger t = _readf(_up); SQInteger t = _readf(_up);
if(t > MAX_CHAR) Error(_SC("Invalid character")); if(t > MAX_CHAR) Error(_SC("Invalid character"));
if(t != 0) { if(t != 0) {
_currdata = (LexChar)t; _currdata = (LexChar)t;
return; return;
} }
_currdata = RABBIT_EOB; _currdata = RABBIT_EOB;
_reached_eof = SQTrue; _reached_eof = SQTrue;
} }
const SQChar *SQLexer::Tok2Str(SQInteger tok) const SQChar *SQLexer::Tok2Str(SQInteger tok)
{ {
SQObjectPtr itr, key, val; SQObjectPtr itr, key, val;
SQInteger nitr; SQInteger nitr;
while((nitr = _keywords->Next(false,itr, key, val)) != -1) { while((nitr = _keywords->Next(false,itr, key, val)) != -1) {
itr = (SQInteger)nitr; itr = (SQInteger)nitr;
if(((SQInteger)_integer(val)) == tok) if(((SQInteger)_integer(val)) == tok)
return _stringval(key); return _stringval(key);
} }
return NULL; return NULL;
} }
void SQLexer::LexBlockComment() void SQLexer::LexBlockComment()
{ {
bool done = false; bool done = false;
while(!done) { while(!done) {
switch(CUR_CHAR) { switch(CUR_CHAR) {
case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue; case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue;
case _SC('\n'): _currentline++; NEXT(); continue; case _SC('\n'): _currentline++; NEXT(); continue;
case RABBIT_EOB: Error(_SC("missing \"*/\" in comment")); case RABBIT_EOB: Error(_SC("missing \"*/\" in comment"));
default: NEXT(); default: NEXT();
} }
} }
} }
void SQLexer::LexLineComment() void SQLexer::LexLineComment()
{ {
do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB())); do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB()));
} }
SQInteger SQLexer::Lex() SQInteger SQLexer::Lex()
{ {
_lasttokenline = _currentline; _lasttokenline = _currentline;
while(CUR_CHAR != RABBIT_EOB) { while(CUR_CHAR != RABBIT_EOB) {
switch(CUR_CHAR){ switch(CUR_CHAR){
case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue; case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue;
case _SC('\n'): case _SC('\n'):
_currentline++; _currentline++;
_prevtoken=_curtoken; _prevtoken=_curtoken;
_curtoken=_SC('\n'); _curtoken=_SC('\n');
NEXT(); NEXT();
_currentcolumn=1; _currentcolumn=1;
continue; continue;
case _SC('#'): LexLineComment(); continue; case _SC('#'): LexLineComment(); continue;
case _SC('/'): case _SC('/'):
NEXT(); NEXT();
switch(CUR_CHAR){ switch(CUR_CHAR){
case _SC('*'): case _SC('*'):
NEXT(); NEXT();
LexBlockComment(); LexBlockComment();
continue; continue;
case _SC('/'): case _SC('/'):
LexLineComment(); LexLineComment();
continue; continue;
case _SC('='): case _SC('='):
NEXT(); NEXT();
RETURN_TOKEN(TK_DIVEQ); RETURN_TOKEN(TK_DIVEQ);
continue; continue;
case _SC('>'): case _SC('>'):
NEXT(); NEXT();
RETURN_TOKEN(TK_ATTR_CLOSE); RETURN_TOKEN(TK_ATTR_CLOSE);
continue; continue;
default: default:
RETURN_TOKEN('/'); RETURN_TOKEN('/');
} }
case _SC('='): case _SC('='):
NEXT(); NEXT();
if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') } if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') }
else { NEXT(); RETURN_TOKEN(TK_EQ); } else { NEXT(); RETURN_TOKEN(TK_EQ); }
case _SC('<'): case _SC('<'):
NEXT(); NEXT();
switch(CUR_CHAR) { switch(CUR_CHAR) {
case _SC('='): case _SC('='):
NEXT(); NEXT();
if(CUR_CHAR == _SC('>')) { if(CUR_CHAR == _SC('>')) {
NEXT(); NEXT();
RETURN_TOKEN(TK_3WAYSCMP); RETURN_TOKEN(TK_3WAYSCMP);
} }
RETURN_TOKEN(TK_LE) RETURN_TOKEN(TK_LE)
break; break;
case _SC('-'): NEXT(); RETURN_TOKEN(TK_NEWSLOT); break; case _SC('-'): NEXT(); RETURN_TOKEN(TK_NEWSLOT); break;
case _SC('<'): NEXT(); RETURN_TOKEN(TK_SHIFTL); break; case _SC('<'): NEXT(); RETURN_TOKEN(TK_SHIFTL); break;
case _SC('/'): NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); break; case _SC('/'): NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); break;
} }
RETURN_TOKEN('<'); RETURN_TOKEN('<');
case _SC('>'): case _SC('>'):
NEXT(); NEXT();
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);} if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);}
else if(CUR_CHAR == _SC('>')){ else if(CUR_CHAR == _SC('>')){
NEXT(); NEXT();
if(CUR_CHAR == _SC('>')){ if(CUR_CHAR == _SC('>')){
NEXT(); NEXT();
RETURN_TOKEN(TK_USHIFTR); RETURN_TOKEN(TK_USHIFTR);
} }
RETURN_TOKEN(TK_SHIFTR); RETURN_TOKEN(TK_SHIFTR);
} }
else { RETURN_TOKEN('>') } else { RETURN_TOKEN('>') }
case _SC('!'): case _SC('!'):
NEXT(); NEXT();
if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')} if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')}
else { NEXT(); RETURN_TOKEN(TK_NE); } else { NEXT(); RETURN_TOKEN(TK_NE); }
case _SC('@'): { case _SC('@'): {
SQInteger stype; SQInteger stype;
NEXT(); NEXT();
if(CUR_CHAR != _SC('"')) { if(CUR_CHAR != _SC('"')) {
RETURN_TOKEN('@'); RETURN_TOKEN('@');
} }
if((stype=ReadString('"',true))!=-1) { if((stype=ReadString('"',true))!=-1) {
RETURN_TOKEN(stype); RETURN_TOKEN(stype);
} }
Error(_SC("error parsing the string")); Error(_SC("error parsing the string"));
} }
case _SC('"'): case _SC('"'):
case _SC('\''): { case _SC('\''): {
SQInteger stype; SQInteger stype;
if((stype=ReadString(CUR_CHAR,false))!=-1){ if((stype=ReadString(CUR_CHAR,false))!=-1){
RETURN_TOKEN(stype); RETURN_TOKEN(stype);
} }
Error(_SC("error parsing the string")); Error(_SC("error parsing the string"));
} }
case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'): case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'):
case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'): case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'):
{SQInteger ret = CUR_CHAR; {SQInteger ret = CUR_CHAR;
NEXT(); RETURN_TOKEN(ret); } NEXT(); RETURN_TOKEN(ret); }
case _SC('.'): case _SC('.'):
NEXT(); NEXT();
if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') } if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') }
NEXT(); NEXT();
if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); } if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); }
NEXT(); NEXT();
RETURN_TOKEN(TK_VARPARAMS); RETURN_TOKEN(TK_VARPARAMS);
case _SC('&'): case _SC('&'):
NEXT(); NEXT();
if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') } if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') }
else { NEXT(); RETURN_TOKEN(TK_AND); } else { NEXT(); RETURN_TOKEN(TK_AND); }
case _SC('|'): case _SC('|'):
NEXT(); NEXT();
if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') } if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') }
else { NEXT(); RETURN_TOKEN(TK_OR); } else { NEXT(); RETURN_TOKEN(TK_OR); }
case _SC(':'): case _SC(':'):
NEXT(); NEXT();
if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') } if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') }
else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); } else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); }
case _SC('*'): case _SC('*'):
NEXT(); NEXT();
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);} if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);}
else RETURN_TOKEN('*'); else RETURN_TOKEN('*');
case _SC('%'): case _SC('%'):
NEXT(); NEXT();
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);} if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);}
else RETURN_TOKEN('%'); else RETURN_TOKEN('%');
case _SC('-'): case _SC('-'):
NEXT(); NEXT();
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);} if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);}
else if (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);} else if (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);}
else RETURN_TOKEN('-'); else RETURN_TOKEN('-');
case _SC('+'): case _SC('+'):
NEXT(); NEXT();
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);} if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);}
else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);} else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);}
else RETURN_TOKEN('+'); else RETURN_TOKEN('+');
case RABBIT_EOB: case RABBIT_EOB:
return 0; return 0;
default:{ default:{
if (scisdigit(CUR_CHAR)) { if (scisdigit(CUR_CHAR)) {
SQInteger ret = ReadNumber(); SQInteger ret = ReadNumber();
RETURN_TOKEN(ret); RETURN_TOKEN(ret);
} }
else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) { else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) {
SQInteger t = ReadID(); SQInteger t = ReadID();
RETURN_TOKEN(t); RETURN_TOKEN(t);
} }
else { else {
SQInteger c = CUR_CHAR; SQInteger c = CUR_CHAR;
if (sciscntrl((int)c)) Error(_SC("unexpected character(control)")); if (sciscntrl((int)c)) Error(_SC("unexpected character(control)"));
NEXT(); NEXT();
RETURN_TOKEN(c); RETURN_TOKEN(c);
} }
RETURN_TOKEN(0); RETURN_TOKEN(0);
} }
} }
} }
return 0; return 0;
} }
SQInteger SQLexer::GetIDType(const SQChar *s,SQInteger len) SQInteger SQLexer::GetIDType(const SQChar *s,SQInteger len)
{ {
SQObjectPtr t; SQObjectPtr t;
if(_keywords->GetStr(s,len, t)) { if(_keywords->GetStr(s,len, t)) {
return SQInteger(_integer(t)); return SQInteger(_integer(t));
} }
return TK_IDENTIFIER; return TK_IDENTIFIER;
} }
#ifdef SQUNICODE #ifdef SQUNICODE
#if WCHAR_SIZE == 2 #if WCHAR_SIZE == 2
SQInteger SQLexer::AddUTF16(SQUnsignedInteger ch) SQInteger SQLexer::AddUTF16(SQUnsignedInteger ch)
{ {
if (ch >= 0x10000) if (ch >= 0x10000)
{ {
SQUnsignedInteger code = (ch - 0x10000); SQUnsignedInteger code = (ch - 0x10000);
APPEND_CHAR((SQChar)(0xD800 | (code >> 10))); APPEND_CHAR((SQChar)(0xD800 | (code >> 10)));
APPEND_CHAR((SQChar)(0xDC00 | (code & 0x3FF))); APPEND_CHAR((SQChar)(0xDC00 | (code & 0x3FF)));
return 2; return 2;
} }
else { else {
APPEND_CHAR((SQChar)ch); APPEND_CHAR((SQChar)ch);
return 1; return 1;
} }
} }
#endif #endif
#else #else
SQInteger SQLexer::AddUTF8(SQUnsignedInteger ch) SQInteger SQLexer::AddUTF8(SQUnsignedInteger ch)
{ {
if (ch < 0x80) { if (ch < 0x80) {
APPEND_CHAR((char)ch); APPEND_CHAR((char)ch);
return 1; return 1;
} }
if (ch < 0x800) { if (ch < 0x800) {
APPEND_CHAR((SQChar)((ch >> 6) | 0xC0)); APPEND_CHAR((SQChar)((ch >> 6) | 0xC0));
APPEND_CHAR((SQChar)((ch & 0x3F) | 0x80)); APPEND_CHAR((SQChar)((ch & 0x3F) | 0x80));
return 2; return 2;
} }
if (ch < 0x10000) { if (ch < 0x10000) {
APPEND_CHAR((SQChar)((ch >> 12) | 0xE0)); APPEND_CHAR((SQChar)((ch >> 12) | 0xE0));
APPEND_CHAR((SQChar)(((ch >> 6) & 0x3F) | 0x80)); APPEND_CHAR((SQChar)(((ch >> 6) & 0x3F) | 0x80));
APPEND_CHAR((SQChar)((ch & 0x3F) | 0x80)); APPEND_CHAR((SQChar)((ch & 0x3F) | 0x80));
return 3; return 3;
} }
if (ch < 0x110000) { if (ch < 0x110000) {
APPEND_CHAR((SQChar)((ch >> 18) | 0xF0)); APPEND_CHAR((SQChar)((ch >> 18) | 0xF0));
APPEND_CHAR((SQChar)(((ch >> 12) & 0x3F) | 0x80)); APPEND_CHAR((SQChar)(((ch >> 12) & 0x3F) | 0x80));
APPEND_CHAR((SQChar)(((ch >> 6) & 0x3F) | 0x80)); APPEND_CHAR((SQChar)(((ch >> 6) & 0x3F) | 0x80));
APPEND_CHAR((SQChar)((ch & 0x3F) | 0x80)); APPEND_CHAR((SQChar)((ch & 0x3F) | 0x80));
return 4; return 4;
} }
return 0; return 0;
} }
#endif #endif
SQInteger SQLexer::ProcessStringHexEscape(SQChar *dest, SQInteger maxdigits) SQInteger SQLexer::ProcessStringHexEscape(SQChar *dest, SQInteger maxdigits)
{ {
NEXT(); NEXT();
if (!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected")); if (!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected"));
SQInteger n = 0; SQInteger n = 0;
while (isxdigit(CUR_CHAR) && n < maxdigits) { while (isxdigit(CUR_CHAR) && n < maxdigits) {
dest[n] = CUR_CHAR; dest[n] = CUR_CHAR;
n++; n++;
NEXT(); NEXT();
} }
dest[n] = 0; dest[n] = 0;
return n; return n;
} }
SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim) SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
{ {
INIT_TEMP_STRING(); INIT_TEMP_STRING();
NEXT(); NEXT();
if(IS_EOB()) return -1; if(IS_EOB()) return -1;
for(;;) { for(;;) {
while(CUR_CHAR != ndelim) { while(CUR_CHAR != ndelim) {
SQInteger x = CUR_CHAR; SQInteger x = CUR_CHAR;
switch (x) { switch (x) {
case RABBIT_EOB: case RABBIT_EOB:
Error(_SC("unfinished string")); Error(_SC("unfinished string"));
return -1; return -1;
case _SC('\n'): case _SC('\n'):
if(!verbatim) Error(_SC("newline in a constant")); if(!verbatim) Error(_SC("newline in a constant"));
APPEND_CHAR(CUR_CHAR); NEXT(); APPEND_CHAR(CUR_CHAR); NEXT();
_currentline++; _currentline++;
break; break;
case _SC('\\'): case _SC('\\'):
if(verbatim) { if(verbatim) {
APPEND_CHAR('\\'); NEXT(); APPEND_CHAR('\\'); NEXT();
} }
else { else {
NEXT(); NEXT();
switch(CUR_CHAR) { switch(CUR_CHAR) {
case _SC('x'): { case _SC('x'): {
const SQInteger maxdigits = sizeof(SQChar) * 2; const SQInteger maxdigits = sizeof(SQChar) * 2;
SQChar temp[maxdigits + 1]; SQChar temp[maxdigits + 1];
ProcessStringHexEscape(temp, maxdigits); ProcessStringHexEscape(temp, maxdigits);
SQChar *stemp; SQChar *stemp;
APPEND_CHAR((SQChar)scstrtoul(temp, &stemp, 16)); APPEND_CHAR((SQChar)scstrtoul(temp, &stemp, 16));
} }
break; break;
case _SC('U'): case _SC('U'):
case _SC('u'): { case _SC('u'): {
const SQInteger maxdigits = CUR_CHAR == 'u' ? 4 : 8; const SQInteger maxdigits = CUR_CHAR == 'u' ? 4 : 8;
SQChar temp[8 + 1]; SQChar temp[8 + 1];
ProcessStringHexEscape(temp, maxdigits); ProcessStringHexEscape(temp, maxdigits);
SQChar *stemp; SQChar *stemp;
#ifdef SQUNICODE #ifdef SQUNICODE
#if WCHAR_SIZE == 2 #if WCHAR_SIZE == 2
AddUTF16(scstrtoul(temp, &stemp, 16)); AddUTF16(scstrtoul(temp, &stemp, 16));
#else #else
APPEND_CHAR((SQChar)scstrtoul(temp, &stemp, 16)); APPEND_CHAR((SQChar)scstrtoul(temp, &stemp, 16));
#endif #endif
#else #else
AddUTF8(scstrtoul(temp, &stemp, 16)); AddUTF8(scstrtoul(temp, &stemp, 16));
#endif #endif
} }
break; break;
case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break; case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break;
case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break; case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break;
case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break; case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break;
case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break; case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break;
case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break; case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break;
case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break; case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break;
case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break; case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break;
case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break; case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break;
case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break; case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break;
case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break; case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break;
case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break; case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break;
default: default:
Error(_SC("unrecognised escaper char")); Error(_SC("unrecognised escaper char"));
break; break;
} }
} }
break; break;
default: default:
APPEND_CHAR(CUR_CHAR); APPEND_CHAR(CUR_CHAR);
NEXT(); NEXT();
} }
} }
NEXT(); NEXT();
if(verbatim && CUR_CHAR == '"') { //double quotation if(verbatim && CUR_CHAR == '"') { //double quotation
APPEND_CHAR(CUR_CHAR); APPEND_CHAR(CUR_CHAR);
NEXT(); NEXT();
} }
else { else {
break; break;
} }
} }
TERMINATE_BUFFER(); TERMINATE_BUFFER();
SQInteger len = _longstr.size()-1; SQInteger len = _longstr.size()-1;
if(ndelim == _SC('\'')) { if(ndelim == _SC('\'')) {
if(len == 0) Error(_SC("empty constant")); if(len == 0) Error(_SC("empty constant"));
if(len > 1) Error(_SC("constant too long")); if(len > 1) Error(_SC("constant too long"));
_nvalue = _longstr[0]; _nvalue = _longstr[0];
return TK_INTEGER; return TK_INTEGER;
} }
_svalue = &_longstr[0]; _svalue = &_longstr[0];
return TK_STRING_LITERAL; return TK_STRING_LITERAL;
} }
void LexHexadecimal(const SQChar *s,SQUnsignedInteger *res) void LexHexadecimal(const SQChar *s,SQUnsignedInteger *res)
{ {
*res = 0; *res = 0;
while(*s != 0) while(*s != 0)
{ {
if(scisdigit(*s)) *res = (*res)*16+((*s++)-'0'); if(scisdigit(*s)) *res = (*res)*16+((*s++)-'0');
else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10); else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10);
else { assert(0); } else { assert(0); }
} }
} }
void LexInteger(const SQChar *s,SQUnsignedInteger *res) void LexInteger(const SQChar *s,SQUnsignedInteger *res)
{ {
*res = 0; *res = 0;
while(*s != 0) while(*s != 0)
{ {
*res = (*res)*10+((*s++)-'0'); *res = (*res)*10+((*s++)-'0');
} }
} }
SQInteger scisodigit(SQInteger c) { return c >= _SC('0') && c <= _SC('7'); } SQInteger scisodigit(SQInteger c) { return c >= _SC('0') && c <= _SC('7'); }
void LexOctal(const SQChar *s,SQUnsignedInteger *res) void LexOctal(const SQChar *s,SQUnsignedInteger *res)
{ {
*res = 0; *res = 0;
while(*s != 0) while(*s != 0)
{ {
if(scisodigit(*s)) *res = (*res)*8+((*s++)-'0'); if(scisodigit(*s)) *res = (*res)*8+((*s++)-'0');
else { assert(0); } else { assert(0); }
} }
} }
SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; } SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; }
@ -489,80 +489,80 @@ SQInteger SQLexer::ReadNumber()
#define THEX 3 #define THEX 3
#define TSCIENTIFIC 4 #define TSCIENTIFIC 4
#define TOCTAL 5 #define TOCTAL 5
SQInteger type = TINT, firstchar = CUR_CHAR; SQInteger type = TINT, firstchar = CUR_CHAR;
SQChar *sTemp; SQChar *sTemp;
INIT_TEMP_STRING(); INIT_TEMP_STRING();
NEXT(); NEXT();
if(firstchar == _SC('0') && (toupper(CUR_CHAR) == _SC('X') || scisodigit(CUR_CHAR)) ) { if(firstchar == _SC('0') && (toupper(CUR_CHAR) == _SC('X') || scisodigit(CUR_CHAR)) ) {
if(scisodigit(CUR_CHAR)) { if(scisodigit(CUR_CHAR)) {
type = TOCTAL; type = TOCTAL;
while(scisodigit(CUR_CHAR)) { while(scisodigit(CUR_CHAR)) {
APPEND_CHAR(CUR_CHAR); APPEND_CHAR(CUR_CHAR);
NEXT(); NEXT();
} }
if(scisdigit(CUR_CHAR)) Error(_SC("invalid octal number")); if(scisdigit(CUR_CHAR)) Error(_SC("invalid octal number"));
} }
else { else {
NEXT(); NEXT();
type = THEX; type = THEX;
while(isxdigit(CUR_CHAR)) { while(isxdigit(CUR_CHAR)) {
APPEND_CHAR(CUR_CHAR); APPEND_CHAR(CUR_CHAR);
NEXT(); NEXT();
} }
if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number")); if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number"));
} }
} }
else { else {
APPEND_CHAR((int)firstchar); APPEND_CHAR((int)firstchar);
while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) { while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) {
if(CUR_CHAR == _SC('.') || isexponent(CUR_CHAR)) type = TFLOAT; if(CUR_CHAR == _SC('.') || isexponent(CUR_CHAR)) type = TFLOAT;
if(isexponent(CUR_CHAR)) { if(isexponent(CUR_CHAR)) {
if(type != TFLOAT) Error(_SC("invalid numeric format")); if(type != TFLOAT) Error(_SC("invalid numeric format"));
type = TSCIENTIFIC; type = TSCIENTIFIC;
APPEND_CHAR(CUR_CHAR); APPEND_CHAR(CUR_CHAR);
NEXT(); NEXT();
if(CUR_CHAR == '+' || CUR_CHAR == '-'){ if(CUR_CHAR == '+' || CUR_CHAR == '-'){
APPEND_CHAR(CUR_CHAR); APPEND_CHAR(CUR_CHAR);
NEXT(); NEXT();
} }
if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected")); if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected"));
} }
APPEND_CHAR(CUR_CHAR); APPEND_CHAR(CUR_CHAR);
NEXT(); NEXT();
} }
} }
TERMINATE_BUFFER(); TERMINATE_BUFFER();
switch(type) { switch(type) {
case TSCIENTIFIC: case TSCIENTIFIC:
case TFLOAT: case TFLOAT:
_fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp); _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp);
return TK_FLOAT; return TK_FLOAT;
case TINT: case TINT:
LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue); LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
return TK_INTEGER; return TK_INTEGER;
case THEX: case THEX:
LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
return TK_INTEGER; return TK_INTEGER;
case TOCTAL: case TOCTAL:
LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
return TK_INTEGER; return TK_INTEGER;
} }
return 0; return 0;
} }
SQInteger SQLexer::ReadID() SQInteger SQLexer::ReadID()
{ {
SQInteger res; SQInteger res;
INIT_TEMP_STRING(); INIT_TEMP_STRING();
do { do {
APPEND_CHAR(CUR_CHAR); APPEND_CHAR(CUR_CHAR);
NEXT(); NEXT();
} while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_')); } while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_'));
TERMINATE_BUFFER(); TERMINATE_BUFFER();
res = GetIDType(&_longstr[0],_longstr.size() - 1); res = GetIDType(&_longstr[0],_longstr.size() - 1);
if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) { if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) {
_svalue = &_longstr[0]; _svalue = &_longstr[0];
} }
return res; return res;
} }

View File

@ -15,45 +15,45 @@ typedef unsigned char LexChar;
struct SQLexer struct SQLexer
{ {
SQLexer(); SQLexer();
~SQLexer(); ~SQLexer();
void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed); void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed);
void Error(const SQChar *err); void Error(const SQChar *err);
SQInteger Lex(); SQInteger Lex();
const SQChar *Tok2Str(SQInteger tok); const SQChar *Tok2Str(SQInteger tok);
private: private:
SQInteger GetIDType(const SQChar *s,SQInteger len); SQInteger GetIDType(const SQChar *s,SQInteger len);
SQInteger ReadString(SQInteger ndelim,bool verbatim); SQInteger ReadString(SQInteger ndelim,bool verbatim);
SQInteger ReadNumber(); SQInteger ReadNumber();
void LexBlockComment(); void LexBlockComment();
void LexLineComment(); void LexLineComment();
SQInteger ReadID(); SQInteger ReadID();
void Next(); void Next();
#ifdef SQUNICODE #ifdef SQUNICODE
#if WCHAR_SIZE == 2 #if WCHAR_SIZE == 2
SQInteger AddUTF16(SQUnsignedInteger ch); SQInteger AddUTF16(SQUnsignedInteger ch);
#endif #endif
#else #else
SQInteger AddUTF8(SQUnsignedInteger ch); SQInteger AddUTF8(SQUnsignedInteger ch);
#endif #endif
SQInteger ProcessStringHexEscape(SQChar *dest, SQInteger maxdigits); SQInteger ProcessStringHexEscape(SQChar *dest, SQInteger maxdigits);
SQInteger _curtoken; SQInteger _curtoken;
SQTable *_keywords; SQTable *_keywords;
SQBool _reached_eof; SQBool _reached_eof;
public: public:
SQInteger _prevtoken; SQInteger _prevtoken;
SQInteger _currentline; SQInteger _currentline;
SQInteger _lasttokenline; SQInteger _lasttokenline;
SQInteger _currentcolumn; SQInteger _currentcolumn;
const SQChar *_svalue; const SQChar *_svalue;
SQInteger _nvalue; SQInteger _nvalue;
SQFloat _fvalue; SQFloat _fvalue;
SQLEXREADFUNC _readf; SQLEXREADFUNC _readf;
SQUserPointer _up; SQUserPointer _up;
LexChar _currdata; LexChar _currdata;
SQSharedState *_sharedstate; SQSharedState *_sharedstate;
sqvector<SQChar> _longstr; sqvector<SQChar> _longstr;
CompilerErrorFunc _errfunc; CompilerErrorFunc _errfunc;
void *_errtarget; void *_errtarget;
}; };

View File

@ -18,539 +18,539 @@
const SQChar *IdType2Name(SQObjectType type) const SQChar *IdType2Name(SQObjectType type)
{ {
switch(_RAW_TYPE(type)) switch(_RAW_TYPE(type))
{ {
case _RT_NULL:return _SC("null"); case _RT_NULL:return _SC("null");
case _RT_INTEGER:return _SC("integer"); case _RT_INTEGER:return _SC("integer");
case _RT_FLOAT:return _SC("float"); case _RT_FLOAT:return _SC("float");
case _RT_BOOL:return _SC("bool"); case _RT_BOOL:return _SC("bool");
case _RT_STRING:return _SC("string"); case _RT_STRING:return _SC("string");
case _RT_TABLE:return _SC("table"); case _RT_TABLE:return _SC("table");
case _RT_ARRAY:return _SC("array"); case _RT_ARRAY:return _SC("array");
case _RT_GENERATOR:return _SC("generator"); case _RT_GENERATOR:return _SC("generator");
case _RT_CLOSURE: case _RT_CLOSURE:
case _RT_NATIVECLOSURE: case _RT_NATIVECLOSURE:
return _SC("function"); return _SC("function");
case _RT_USERDATA: case _RT_USERDATA:
case _RT_USERPOINTER: case _RT_USERPOINTER:
return _SC("userdata"); return _SC("userdata");
case _RT_THREAD: return _SC("thread"); case _RT_THREAD: return _SC("thread");
case _RT_FUNCPROTO: return _SC("function"); case _RT_FUNCPROTO: return _SC("function");
case _RT_CLASS: return _SC("class"); case _RT_CLASS: return _SC("class");
case _RT_INSTANCE: return _SC("instance"); case _RT_INSTANCE: return _SC("instance");
case _RT_WEAKREF: return _SC("weakref"); case _RT_WEAKREF: return _SC("weakref");
case _RT_OUTER: return _SC("outer"); case _RT_OUTER: return _SC("outer");
default: default:
return NULL; return NULL;
} }
} }
const SQChar *GetTypeName(const SQObjectPtr &obj1) const SQChar *GetTypeName(const SQObjectPtr &obj1)
{ {
return IdType2Name(sq_type(obj1)); return IdType2Name(sq_type(obj1));
} }
SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len) SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len)
{ {
SQString *str=ADD_STRING(ss,s,len); SQString *str=ADD_STRING(ss,s,len);
return str; return str;
} }
void SQString::Release() void SQString::Release()
{ {
REMOVE_STRING(_sharedstate,this); REMOVE_STRING(_sharedstate,this);
} }
SQInteger SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) SQInteger SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
{ {
SQInteger idx = (SQInteger)TranslateIndex(refpos); SQInteger idx = (SQInteger)TranslateIndex(refpos);
while(idx < _len){ while(idx < _len){
outkey = (SQInteger)idx; outkey = (SQInteger)idx;
outval = (SQInteger)((SQUnsignedInteger)_val[idx]); outval = (SQInteger)((SQUnsignedInteger)_val[idx]);
//return idx for the next iteration //return idx for the next iteration
return ++idx; return ++idx;
} }
//nothing to iterate anymore //nothing to iterate anymore
return -1; return -1;
} }
SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx) SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx)
{ {
switch(sq_type(idx)){ switch(sq_type(idx)){
case OT_NULL: case OT_NULL:
return 0; return 0;
case OT_INTEGER: case OT_INTEGER:
return (SQUnsignedInteger)_integer(idx); return (SQUnsignedInteger)_integer(idx);
default: assert(0); break; default: assert(0); break;
} }
return 0; return 0;
} }
SQWeakRef *SQRefCounted::GetWeakRef(SQObjectType type) SQWeakRef *SQRefCounted::GetWeakRef(SQObjectType type)
{ {
if(!_weakref) { if(!_weakref) {
sq_new(_weakref,SQWeakRef); sq_new(_weakref,SQWeakRef);
#if defined(SQUSEDOUBLE) && !defined(_SQ64) #if defined(SQUSEDOUBLE) && !defined(_SQ64)
_weakref->_obj._unVal.raw = 0; //clean the whole union on 32 bits with double _weakref->_obj._unVal.raw = 0; //clean the whole union on 32 bits with double
#endif #endif
_weakref->_obj._type = type; _weakref->_obj._type = type;
_weakref->_obj._unVal.pRefCounted = this; _weakref->_obj._unVal.pRefCounted = this;
} }
return _weakref; return _weakref;
} }
SQRefCounted::~SQRefCounted() SQRefCounted::~SQRefCounted()
{ {
if(_weakref) { if(_weakref) {
_weakref->_obj._type = OT_NULL; _weakref->_obj._type = OT_NULL;
_weakref->_obj._unVal.pRefCounted = NULL; _weakref->_obj._unVal.pRefCounted = NULL;
} }
} }
void SQWeakRef::Release() { void SQWeakRef::Release() {
if(ISREFCOUNTED(_obj._type)) { if(ISREFCOUNTED(_obj._type)) {
_obj._unVal.pRefCounted->_weakref = NULL; _obj._unVal.pRefCounted->_weakref = NULL;
} }
sq_delete(this,SQWeakRef); sq_delete(this,SQWeakRef);
} }
bool SQDelegable::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) { bool SQDelegable::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) {
if(_delegate) { if(_delegate) {
return _delegate->Get((*_ss(v)->_metamethods)[mm],res); return _delegate->Get((*_ss(v)->_metamethods)[mm],res);
} }
return false; return false;
} }
bool SQDelegable::SetDelegate(SQTable *mt) bool SQDelegable::SetDelegate(SQTable *mt)
{ {
SQTable *temp = mt; SQTable *temp = mt;
if(temp == this) return false; if(temp == this) return false;
while (temp) { while (temp) {
if (temp->_delegate == this) return false; //cycle detected if (temp->_delegate == this) return false; //cycle detected
temp = temp->_delegate; temp = temp->_delegate;
} }
if (mt) __ObjAddRef(mt); if (mt) __ObjAddRef(mt);
__ObjRelease(_delegate); __ObjRelease(_delegate);
_delegate = mt; _delegate = mt;
return true; return true;
} }
bool SQGenerator::Yield(SQVM *v,SQInteger target) bool SQGenerator::Yield(SQVM *v,SQInteger target)
{ {
if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator")); return false;} if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator")); return false;}
if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; } if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; }
SQInteger size = v->_top-v->_stackbase; SQInteger size = v->_top-v->_stackbase;
_stack.resize(size); _stack.resize(size);
SQObject _this = v->_stack[v->_stackbase]; SQObject _this = v->_stack[v->_stackbase];
_stack._vals[0] = ISREFCOUNTED(sq_type(_this)) ? SQObjectPtr(_refcounted(_this)->GetWeakRef(sq_type(_this))) : _this; _stack._vals[0] = ISREFCOUNTED(sq_type(_this)) ? SQObjectPtr(_refcounted(_this)->GetWeakRef(sq_type(_this))) : _this;
for(SQInteger n =1; n<target; n++) { for(SQInteger n =1; n<target; n++) {
_stack._vals[n] = v->_stack[v->_stackbase+n]; _stack._vals[n] = v->_stack[v->_stackbase+n];
} }
for(SQInteger j =0; j < size; j++) for(SQInteger j =0; j < size; j++)
{ {
v->_stack[v->_stackbase+j].Null(); v->_stack[v->_stackbase+j].Null();
} }
_ci = *v->ci; _ci = *v->ci;
_ci._generator=NULL; _ci._generator=NULL;
for(SQInteger i=0;i<_ci._etraps;i++) { for(SQInteger i=0;i<_ci._etraps;i++) {
_etraps.push_back(v->_etraps.top()); _etraps.push_back(v->_etraps.top());
v->_etraps.pop_back(); v->_etraps.pop_back();
// store relative stack base and size in case of resume to other _top // store relative stack base and size in case of resume to other _top
SQExceptionTrap &et = _etraps.back(); SQExceptionTrap &et = _etraps.back();
et._stackbase -= v->_stackbase; et._stackbase -= v->_stackbase;
et._stacksize -= v->_stackbase; et._stacksize -= v->_stackbase;
} }
_state=eSuspended; _state=eSuspended;
return true; return true;
} }
bool SQGenerator::Resume(SQVM *v,SQObjectPtr &dest) bool SQGenerator::Resume(SQVM *v,SQObjectPtr &dest)
{ {
if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; } if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; }
if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; } if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; }
SQInteger size = _stack.size(); SQInteger size = _stack.size();
SQInteger target = &dest - &(v->_stack._vals[v->_stackbase]); SQInteger target = &dest - &(v->_stack._vals[v->_stackbase]);
assert(target>=0 && target<=255); assert(target>=0 && target<=255);
SQInteger newbase = v->_top; SQInteger newbase = v->_top;
if(!v->EnterFrame(v->_top, v->_top + size, false)) if(!v->EnterFrame(v->_top, v->_top + size, false))
return false; return false;
v->ci->_generator = this; v->ci->_generator = this;
v->ci->_target = (SQInt32)target; v->ci->_target = (SQInt32)target;
v->ci->_closure = _ci._closure; v->ci->_closure = _ci._closure;
v->ci->_ip = _ci._ip; v->ci->_ip = _ci._ip;
v->ci->_literals = _ci._literals; v->ci->_literals = _ci._literals;
v->ci->_ncalls = _ci._ncalls; v->ci->_ncalls = _ci._ncalls;
v->ci->_etraps = _ci._etraps; v->ci->_etraps = _ci._etraps;
v->ci->_root = _ci._root; v->ci->_root = _ci._root;
for(SQInteger i=0;i<_ci._etraps;i++) { for(SQInteger i=0;i<_ci._etraps;i++) {
v->_etraps.push_back(_etraps.top()); v->_etraps.push_back(_etraps.top());
_etraps.pop_back(); _etraps.pop_back();
SQExceptionTrap &et = v->_etraps.back(); SQExceptionTrap &et = v->_etraps.back();
// restore absolute stack base and size // restore absolute stack base and size
et._stackbase += newbase; et._stackbase += newbase;
et._stacksize += newbase; et._stacksize += newbase;
} }
SQObject _this = _stack._vals[0]; SQObject _this = _stack._vals[0];
v->_stack[v->_stackbase] = sq_type(_this) == OT_WEAKREF ? _weakref(_this)->_obj : _this; v->_stack[v->_stackbase] = sq_type(_this) == OT_WEAKREF ? _weakref(_this)->_obj : _this;
for(SQInteger n = 1; n<size; n++) { for(SQInteger n = 1; n<size; n++) {
v->_stack[v->_stackbase+n] = _stack._vals[n]; v->_stack[v->_stackbase+n] = _stack._vals[n];
_stack._vals[n].Null(); _stack._vals[n].Null();
} }
_state=eRunning; _state=eRunning;
if (v->_debughook) if (v->_debughook)
v->CallDebugHook(_SC('c')); v->CallDebugHook(_SC('c'));
return true; return true;
} }
void SQArray::Extend(const SQArray *a){ void SQArray::Extend(const SQArray *a){
SQInteger xlen; SQInteger xlen;
if((xlen=a->Size())) if((xlen=a->Size()))
for(SQInteger i=0;i<xlen;i++) for(SQInteger i=0;i<xlen;i++)
Append(a->_values[i]); Append(a->_values[i]);
} }
const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop) const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop)
{ {
SQUnsignedInteger nvars=_nlocalvarinfos; SQUnsignedInteger nvars=_nlocalvarinfos;
const SQChar *res=NULL; const SQChar *res=NULL;
if(nvars>=nseq){ if(nvars>=nseq){
for(SQUnsignedInteger i=0;i<nvars;i++){ for(SQUnsignedInteger i=0;i<nvars;i++){
if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop) if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop)
{ {
if(nseq==0){ if(nseq==0){
vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]); vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]);
res=_stringval(_localvarinfos[i]._name); res=_stringval(_localvarinfos[i]._name);
break; break;
} }
nseq--; nseq--;
} }
} }
} }
return res; return res;
} }
SQInteger SQFunctionProto::GetLine(SQInstruction *curr) SQInteger SQFunctionProto::GetLine(SQInstruction *curr)
{ {
SQInteger op = (SQInteger)(curr-_instructions); SQInteger op = (SQInteger)(curr-_instructions);
SQInteger line=_lineinfos[0]._line; SQInteger line=_lineinfos[0]._line;
SQInteger low = 0; SQInteger low = 0;
SQInteger high = _nlineinfos - 1; SQInteger high = _nlineinfos - 1;
SQInteger mid = 0; SQInteger mid = 0;
while(low <= high) while(low <= high)
{ {
mid = low + ((high - low) >> 1); mid = low + ((high - low) >> 1);
SQInteger curop = _lineinfos[mid]._op; SQInteger curop = _lineinfos[mid]._op;
if(curop > op) if(curop > op)
{ {
high = mid - 1; high = mid - 1;
} }
else if(curop < op) { else if(curop < op) {
if(mid < (_nlineinfos - 1) if(mid < (_nlineinfos - 1)
&& _lineinfos[mid + 1]._op >= op) { && _lineinfos[mid + 1]._op >= op) {
break; break;
} }
low = mid + 1; low = mid + 1;
} }
else { //equal else { //equal
break; break;
} }
} }
while(mid > 0 && _lineinfos[mid]._op >= op) mid--; while(mid > 0 && _lineinfos[mid]._op >= op) mid--;
line = _lineinfos[mid]._line; line = _lineinfos[mid]._line;
return line; return line;
} }
SQClosure::~SQClosure() SQClosure::~SQClosure()
{ {
__ObjRelease(_root); __ObjRelease(_root);
__ObjRelease(_env); __ObjRelease(_env);
__ObjRelease(_base); __ObjRelease(_base);
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
} }
#define _CHECK_IO(exp) { if(!exp)return false; } #define _CHECK_IO(exp) { if(!exp)return false; }
bool SafeWrite(HRABBITVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size) bool SafeWrite(HRABBITVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size)
{ {
if(write(up,dest,size) != size) { if(write(up,dest,size) != size) {
v->Raise_Error(_SC("io error (write function failure)")); v->Raise_Error(_SC("io error (write function failure)"));
return false; return false;
} }
return true; return true;
} }
bool SafeRead(HRABBITVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size) bool SafeRead(HRABBITVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size)
{ {
if(size && read(up,dest,size) != size) { if(size && read(up,dest,size) != size) {
v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated")); v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated"));
return false; return false;
} }
return true; return true;
} }
bool WriteTag(HRABBITVM v,SQWRITEFUNC write,SQUserPointer up,SQUnsignedInteger32 tag) bool WriteTag(HRABBITVM v,SQWRITEFUNC write,SQUserPointer up,SQUnsignedInteger32 tag)
{ {
return SafeWrite(v,write,up,&tag,sizeof(tag)); return SafeWrite(v,write,up,&tag,sizeof(tag));
} }
bool CheckTag(HRABBITVM v,SQWRITEFUNC read,SQUserPointer up,SQUnsignedInteger32 tag) bool CheckTag(HRABBITVM v,SQWRITEFUNC read,SQUserPointer up,SQUnsignedInteger32 tag)
{ {
SQUnsignedInteger32 t; SQUnsignedInteger32 t;
_CHECK_IO(SafeRead(v,read,up,&t,sizeof(t))); _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t)));
if(t != tag){ if(t != tag){
v->Raise_Error(_SC("invalid or corrupted closure stream")); v->Raise_Error(_SC("invalid or corrupted closure stream"));
return false; return false;
} }
return true; return true;
} }
bool WriteObject(HRABBITVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o) bool WriteObject(HRABBITVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o)
{ {
SQUnsignedInteger32 _type = (SQUnsignedInteger32)sq_type(o); SQUnsignedInteger32 _type = (SQUnsignedInteger32)sq_type(o);
_CHECK_IO(SafeWrite(v,write,up,&_type,sizeof(_type))); _CHECK_IO(SafeWrite(v,write,up,&_type,sizeof(_type)));
switch(sq_type(o)){ switch(sq_type(o)){
case OT_STRING: case OT_STRING:
_CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger))); _CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger)));
_CHECK_IO(SafeWrite(v,write,up,_stringval(o),sq_rsl(_string(o)->_len))); _CHECK_IO(SafeWrite(v,write,up,_stringval(o),sq_rsl(_string(o)->_len)));
break; break;
case OT_BOOL: case OT_BOOL:
case OT_INTEGER: case OT_INTEGER:
_CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break; _CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break;
case OT_FLOAT: case OT_FLOAT:
_CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break; _CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break;
case OT_NULL: case OT_NULL:
break; break;
default: default:
v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o)); v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o));
return false; return false;
} }
return true; return true;
} }
bool ReadObject(HRABBITVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o) bool ReadObject(HRABBITVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o)
{ {
SQUnsignedInteger32 _type; SQUnsignedInteger32 _type;
_CHECK_IO(SafeRead(v,read,up,&_type,sizeof(_type))); _CHECK_IO(SafeRead(v,read,up,&_type,sizeof(_type)));
SQObjectType t = (SQObjectType)_type; SQObjectType t = (SQObjectType)_type;
switch(t){ switch(t){
case OT_STRING:{ case OT_STRING:{
SQInteger len; SQInteger len;
_CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger))); _CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger)));
_CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(sq_rsl(len)),sq_rsl(len))); _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(sq_rsl(len)),sq_rsl(len)));
o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len); o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len);
} }
break; break;
case OT_INTEGER:{ case OT_INTEGER:{
SQInteger i; SQInteger i;
_CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break; _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break;
} }
case OT_BOOL:{ case OT_BOOL:{
SQInteger i; SQInteger i;
_CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o._type = OT_BOOL; o._unVal.nInteger = i; break; _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o._type = OT_BOOL; o._unVal.nInteger = i; break;
} }
case OT_FLOAT:{ case OT_FLOAT:{
SQFloat f; SQFloat f;
_CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break; _CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break;
} }
case OT_NULL: case OT_NULL:
o.Null(); o.Null();
break; break;
default: default:
v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t)); v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t));
return false; return false;
} }
return true; return true;
} }
bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
{ {
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD)); _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD));
_CHECK_IO(WriteTag(v,write,up,sizeof(SQChar))); _CHECK_IO(WriteTag(v,write,up,sizeof(SQChar)));
_CHECK_IO(WriteTag(v,write,up,sizeof(SQInteger))); _CHECK_IO(WriteTag(v,write,up,sizeof(SQInteger)));
_CHECK_IO(WriteTag(v,write,up,sizeof(SQFloat))); _CHECK_IO(WriteTag(v,write,up,sizeof(SQFloat)));
_CHECK_IO(_function->Save(v,up,write)); _CHECK_IO(_function->Save(v,up,write));
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL)); _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL));
return true; return true;
} }
bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret) bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret)
{ {
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD)); _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD));
_CHECK_IO(CheckTag(v,read,up,sizeof(SQChar))); _CHECK_IO(CheckTag(v,read,up,sizeof(SQChar)));
_CHECK_IO(CheckTag(v,read,up,sizeof(SQInteger))); _CHECK_IO(CheckTag(v,read,up,sizeof(SQInteger)));
_CHECK_IO(CheckTag(v,read,up,sizeof(SQFloat))); _CHECK_IO(CheckTag(v,read,up,sizeof(SQFloat)));
SQObjectPtr func; SQObjectPtr func;
_CHECK_IO(SQFunctionProto::Load(v,up,read,func)); _CHECK_IO(SQFunctionProto::Load(v,up,read,func));
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL)); _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL));
ret = SQClosure::Create(_ss(v),_funcproto(func),_table(v->_roottable)->GetWeakRef(OT_TABLE)); ret = SQClosure::Create(_ss(v),_funcproto(func),_table(v->_roottable)->GetWeakRef(OT_TABLE));
//FIXME: load an root for this closure //FIXME: load an root for this closure
return true; return true;
} }
SQFunctionProto::SQFunctionProto(SQSharedState *ss) SQFunctionProto::SQFunctionProto(SQSharedState *ss)
{ {
_stacksize=0; _stacksize=0;
_bgenerator=false; _bgenerator=false;
INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);
} }
SQFunctionProto::~SQFunctionProto() SQFunctionProto::~SQFunctionProto()
{ {
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
} }
bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
{ {
SQInteger i,nliterals = _nliterals,nparameters = _nparameters; SQInteger i,nliterals = _nliterals,nparameters = _nparameters;
SQInteger noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos; SQInteger noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos;
SQInteger nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions; SQInteger nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions;
SQInteger ndefaultparams = _ndefaultparams; SQInteger ndefaultparams = _ndefaultparams;
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
_CHECK_IO(WriteObject(v,up,write,_sourcename)); _CHECK_IO(WriteObject(v,up,write,_sourcename));
_CHECK_IO(WriteObject(v,up,write,_name)); _CHECK_IO(WriteObject(v,up,write,_name));
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
_CHECK_IO(SafeWrite(v,write,up,&nliterals,sizeof(nliterals))); _CHECK_IO(SafeWrite(v,write,up,&nliterals,sizeof(nliterals)));
_CHECK_IO(SafeWrite(v,write,up,&nparameters,sizeof(nparameters))); _CHECK_IO(SafeWrite(v,write,up,&nparameters,sizeof(nparameters)));
_CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues))); _CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues)));
_CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos))); _CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos)));
_CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos))); _CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos)));
_CHECK_IO(SafeWrite(v,write,up,&ndefaultparams,sizeof(ndefaultparams))); _CHECK_IO(SafeWrite(v,write,up,&ndefaultparams,sizeof(ndefaultparams)));
_CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions))); _CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions)));
_CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions))); _CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions)));
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
for(i=0;i<nliterals;i++){ for(i=0;i<nliterals;i++){
_CHECK_IO(WriteObject(v,up,write,_literals[i])); _CHECK_IO(WriteObject(v,up,write,_literals[i]));
} }
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
for(i=0;i<nparameters;i++){ for(i=0;i<nparameters;i++){
_CHECK_IO(WriteObject(v,up,write,_parameters[i])); _CHECK_IO(WriteObject(v,up,write,_parameters[i]));
} }
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
for(i=0;i<noutervalues;i++){ for(i=0;i<noutervalues;i++){
_CHECK_IO(SafeWrite(v,write,up,&_outervalues[i]._type,sizeof(SQUnsignedInteger))); _CHECK_IO(SafeWrite(v,write,up,&_outervalues[i]._type,sizeof(SQUnsignedInteger)));
_CHECK_IO(WriteObject(v,up,write,_outervalues[i]._src)); _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._src));
_CHECK_IO(WriteObject(v,up,write,_outervalues[i]._name)); _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._name));
} }
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
for(i=0;i<nlocalvarinfos;i++){ for(i=0;i<nlocalvarinfos;i++){
SQLocalVarInfo &lvi=_localvarinfos[i]; SQLocalVarInfo &lvi=_localvarinfos[i];
_CHECK_IO(WriteObject(v,up,write,lvi._name)); _CHECK_IO(WriteObject(v,up,write,lvi._name));
_CHECK_IO(SafeWrite(v,write,up,&lvi._pos,sizeof(SQUnsignedInteger))); _CHECK_IO(SafeWrite(v,write,up,&lvi._pos,sizeof(SQUnsignedInteger)));
_CHECK_IO(SafeWrite(v,write,up,&lvi._start_op,sizeof(SQUnsignedInteger))); _CHECK_IO(SafeWrite(v,write,up,&lvi._start_op,sizeof(SQUnsignedInteger)));
_CHECK_IO(SafeWrite(v,write,up,&lvi._end_op,sizeof(SQUnsignedInteger))); _CHECK_IO(SafeWrite(v,write,up,&lvi._end_op,sizeof(SQUnsignedInteger)));
} }
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
_CHECK_IO(SafeWrite(v,write,up,_lineinfos,sizeof(SQLineInfo)*nlineinfos)); _CHECK_IO(SafeWrite(v,write,up,_lineinfos,sizeof(SQLineInfo)*nlineinfos));
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
_CHECK_IO(SafeWrite(v,write,up,_defaultparams,sizeof(SQInteger)*ndefaultparams)); _CHECK_IO(SafeWrite(v,write,up,_defaultparams,sizeof(SQInteger)*ndefaultparams));
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
_CHECK_IO(SafeWrite(v,write,up,_instructions,sizeof(SQInstruction)*ninstructions)); _CHECK_IO(SafeWrite(v,write,up,_instructions,sizeof(SQInstruction)*ninstructions));
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
for(i=0;i<nfunctions;i++){ for(i=0;i<nfunctions;i++){
_CHECK_IO(_funcproto(_functions[i])->Save(v,up,write)); _CHECK_IO(_funcproto(_functions[i])->Save(v,up,write));
} }
_CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize))); _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize)));
_CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator))); _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator)));
_CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams))); _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams)));
return true; return true;
} }
bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret) bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret)
{ {
SQInteger i, nliterals,nparameters; SQInteger i, nliterals,nparameters;
SQInteger noutervalues ,nlocalvarinfos ; SQInteger noutervalues ,nlocalvarinfos ;
SQInteger nlineinfos,ninstructions ,nfunctions,ndefaultparams ; SQInteger nlineinfos,ninstructions ,nfunctions,ndefaultparams ;
SQObjectPtr sourcename, name; SQObjectPtr sourcename, name;
SQObjectPtr o; SQObjectPtr o;
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
_CHECK_IO(ReadObject(v, up, read, sourcename)); _CHECK_IO(ReadObject(v, up, read, sourcename));
_CHECK_IO(ReadObject(v, up, read, name)); _CHECK_IO(ReadObject(v, up, read, name));
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
_CHECK_IO(SafeRead(v,read,up, &nliterals, sizeof(nliterals))); _CHECK_IO(SafeRead(v,read,up, &nliterals, sizeof(nliterals)));
_CHECK_IO(SafeRead(v,read,up, &nparameters, sizeof(nparameters))); _CHECK_IO(SafeRead(v,read,up, &nparameters, sizeof(nparameters)));
_CHECK_IO(SafeRead(v,read,up, &noutervalues, sizeof(noutervalues))); _CHECK_IO(SafeRead(v,read,up, &noutervalues, sizeof(noutervalues)));
_CHECK_IO(SafeRead(v,read,up, &nlocalvarinfos, sizeof(nlocalvarinfos))); _CHECK_IO(SafeRead(v,read,up, &nlocalvarinfos, sizeof(nlocalvarinfos)));
_CHECK_IO(SafeRead(v,read,up, &nlineinfos, sizeof(nlineinfos))); _CHECK_IO(SafeRead(v,read,up, &nlineinfos, sizeof(nlineinfos)));
_CHECK_IO(SafeRead(v,read,up, &ndefaultparams, sizeof(ndefaultparams))); _CHECK_IO(SafeRead(v,read,up, &ndefaultparams, sizeof(ndefaultparams)));
_CHECK_IO(SafeRead(v,read,up, &ninstructions, sizeof(ninstructions))); _CHECK_IO(SafeRead(v,read,up, &ninstructions, sizeof(ninstructions)));
_CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions))); _CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions)));
SQFunctionProto *f = SQFunctionProto::Create(NULL,ninstructions,nliterals,nparameters, SQFunctionProto *f = SQFunctionProto::Create(NULL,ninstructions,nliterals,nparameters,
nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams); nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams);
SQObjectPtr proto = f; //gets a ref in case of failure SQObjectPtr proto = f; //gets a ref in case of failure
f->_sourcename = sourcename; f->_sourcename = sourcename;
f->_name = name; f->_name = name;
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
for(i = 0;i < nliterals; i++){ for(i = 0;i < nliterals; i++){
_CHECK_IO(ReadObject(v, up, read, o)); _CHECK_IO(ReadObject(v, up, read, o));
f->_literals[i] = o; f->_literals[i] = o;
} }
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
for(i = 0; i < nparameters; i++){ for(i = 0; i < nparameters; i++){
_CHECK_IO(ReadObject(v, up, read, o)); _CHECK_IO(ReadObject(v, up, read, o));
f->_parameters[i] = o; f->_parameters[i] = o;
} }
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
for(i = 0; i < noutervalues; i++){ for(i = 0; i < noutervalues; i++){
SQUnsignedInteger type; SQUnsignedInteger type;
SQObjectPtr name; SQObjectPtr name;
_CHECK_IO(SafeRead(v,read,up, &type, sizeof(SQUnsignedInteger))); _CHECK_IO(SafeRead(v,read,up, &type, sizeof(SQUnsignedInteger)));
_CHECK_IO(ReadObject(v, up, read, o)); _CHECK_IO(ReadObject(v, up, read, o));
_CHECK_IO(ReadObject(v, up, read, name)); _CHECK_IO(ReadObject(v, up, read, name));
f->_outervalues[i] = SQOuterVar(name,o, (SQOuterType)type); f->_outervalues[i] = SQOuterVar(name,o, (SQOuterType)type);
} }
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
for(i = 0; i < nlocalvarinfos; i++){ for(i = 0; i < nlocalvarinfos; i++){
SQLocalVarInfo lvi; SQLocalVarInfo lvi;
_CHECK_IO(ReadObject(v, up, read, lvi._name)); _CHECK_IO(ReadObject(v, up, read, lvi._name));
_CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(SQUnsignedInteger))); _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(SQUnsignedInteger)));
_CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(SQUnsignedInteger))); _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(SQUnsignedInteger)));
_CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(SQUnsignedInteger))); _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(SQUnsignedInteger)));
f->_localvarinfos[i] = lvi; f->_localvarinfos[i] = lvi;
} }
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
_CHECK_IO(SafeRead(v,read,up, f->_lineinfos, sizeof(SQLineInfo)*nlineinfos)); _CHECK_IO(SafeRead(v,read,up, f->_lineinfos, sizeof(SQLineInfo)*nlineinfos));
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
_CHECK_IO(SafeRead(v,read,up, f->_defaultparams, sizeof(SQInteger)*ndefaultparams)); _CHECK_IO(SafeRead(v,read,up, f->_defaultparams, sizeof(SQInteger)*ndefaultparams));
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
_CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(SQInstruction)*ninstructions)); _CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(SQInstruction)*ninstructions));
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
for(i = 0; i < nfunctions; i++){ for(i = 0; i < nfunctions; i++){
_CHECK_IO(_funcproto(o)->Load(v, up, read, o)); _CHECK_IO(_funcproto(o)->Load(v, up, read, o));
f->_functions[i] = o; f->_functions[i] = o;
} }
_CHECK_IO(SafeRead(v,read,up, &f->_stacksize, sizeof(f->_stacksize))); _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->_bgenerator, sizeof(f->_bgenerator)));
_CHECK_IO(SafeRead(v,read,up, &f->_varparams, sizeof(f->_varparams))); _CHECK_IO(SafeRead(v,read,up, &f->_varparams, sizeof(f->_varparams)));
ret = f; ret = f;
return true; return true;
} }

View File

@ -22,39 +22,39 @@
struct SQSharedState; struct SQSharedState;
enum SQMetaMethod{ enum SQMetaMethod{
MT_ADD=0, MT_ADD=0,
MT_SUB=1, MT_SUB=1,
MT_MUL=2, MT_MUL=2,
MT_DIV=3, MT_DIV=3,
MT_UNM=4, MT_UNM=4,
MT_MODULO=5, MT_MODULO=5,
MT_SET=6, MT_SET=6,
MT_GET=7, MT_GET=7,
MT_TYPEOF=8, MT_TYPEOF=8,
MT_NEXTI=9, MT_NEXTI=9,
MT_CMP=10, MT_CMP=10,
MT_CALL=11, MT_CALL=11,
MT_CLONED=12, MT_CLONED=12,
MT_NEWSLOT=13, MT_NEWSLOT=13,
MT_DELSLOT=14, MT_DELSLOT=14,
MT_TOSTRING=15, MT_TOSTRING=15,
MT_NEWMEMBER=16, MT_NEWMEMBER=16,
MT_INHERITED=17, MT_INHERITED=17,
MT_LAST = 18 MT_LAST = 18
}; };
#define MM_ADD _SC("_add") #define MM_ADD _SC("_add")
#define MM_SUB _SC("_sub") #define MM_SUB _SC("_sub")
#define MM_MUL _SC("_mul") #define MM_MUL _SC("_mul")
#define MM_DIV _SC("_div") #define MM_DIV _SC("_div")
#define MM_UNM _SC("_unm") #define MM_UNM _SC("_unm")
#define MM_MODULO _SC("_modulo") #define MM_MODULO _SC("_modulo")
#define MM_SET _SC("_set") #define MM_SET _SC("_set")
#define MM_GET _SC("_get") #define MM_GET _SC("_get")
#define MM_TYPEOF _SC("_typeof") #define MM_TYPEOF _SC("_typeof")
#define MM_NEXTI _SC("_nexti") #define MM_NEXTI _SC("_nexti")
#define MM_CMP _SC("_cmp") #define MM_CMP _SC("_cmp")
#define MM_CALL _SC("_call") #define MM_CALL _SC("_call")
#define MM_CLONED _SC("_cloned") #define MM_CLONED _SC("_cloned")
#define MM_NEWSLOT _SC("_newslot") #define MM_NEWSLOT _SC("_newslot")
#define MM_DELSLOT _SC("_delslot") #define MM_DELSLOT _SC("_delslot")
@ -64,46 +64,46 @@ enum SQMetaMethod{
#define _CONSTRUCT_VECTOR(type,size,ptr) { \ #define _CONSTRUCT_VECTOR(type,size,ptr) { \
for(SQInteger n = 0; n < ((SQInteger)size); n++) { \ for(SQInteger n = 0; n < ((SQInteger)size); n++) { \
new (&ptr[n]) type(); \ new (&ptr[n]) type(); \
} \ } \
} }
#define _DESTRUCT_VECTOR(type,size,ptr) { \ #define _DESTRUCT_VECTOR(type,size,ptr) { \
for(SQInteger nl = 0; nl < ((SQInteger)size); nl++) { \ for(SQInteger nl = 0; nl < ((SQInteger)size); nl++) { \
ptr[nl].~type(); \ ptr[nl].~type(); \
} \ } \
} }
#define _COPY_VECTOR(dest,src,size) { \ #define _COPY_VECTOR(dest,src,size) { \
for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \ for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \
dest[_n_] = src[_n_]; \ dest[_n_] = src[_n_]; \
} \ } \
} }
#define _NULL_SQOBJECT_VECTOR(vec,size) { \ #define _NULL_SQOBJECT_VECTOR(vec,size) { \
for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \ for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \
vec[_n_].Null(); \ vec[_n_].Null(); \
} \ } \
} }
#define MINPOWER2 4 #define MINPOWER2 4
struct SQRefCounted struct SQRefCounted
{ {
SQUnsignedInteger _uiRef; SQUnsignedInteger _uiRef;
struct SQWeakRef *_weakref; struct SQWeakRef *_weakref;
SQRefCounted() { _uiRef = 0; _weakref = NULL; } SQRefCounted() { _uiRef = 0; _weakref = NULL; }
virtual ~SQRefCounted(); virtual ~SQRefCounted();
SQWeakRef *GetWeakRef(SQObjectType type); SQWeakRef *GetWeakRef(SQObjectType type);
virtual void Release()=0; virtual void Release()=0;
}; };
struct SQWeakRef : SQRefCounted struct SQWeakRef : SQRefCounted
{ {
void Release(); void Release();
SQObject _obj; SQObject _obj;
}; };
#define _realval(o) (sq_type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj) #define _realval(o) (sq_type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj)
@ -111,26 +111,26 @@ struct SQWeakRef : SQRefCounted
struct SQObjectPtr; struct SQObjectPtr;
#define __AddRef(type,unval) if(ISREFCOUNTED(type)) \ #define __AddRef(type,unval) if(ISREFCOUNTED(type)) \
{ \ { \
unval.pRefCounted->_uiRef++; \ unval.pRefCounted->_uiRef++; \
} }
#define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)==0)) \ #define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)==0)) \
{ \ { \
unval.pRefCounted->Release(); \ unval.pRefCounted->Release(); \
} }
#define __ObjRelease(obj) { \ #define __ObjRelease(obj) { \
if((obj)) { \ if((obj)) { \
(obj)->_uiRef--; \ (obj)->_uiRef--; \
if((obj)->_uiRef == 0) \ if((obj)->_uiRef == 0) \
(obj)->Release(); \ (obj)->Release(); \
(obj) = NULL; \ (obj) = NULL; \
} \ } \
} }
#define __ObjAddRef(obj) { \ #define __ObjAddRef(obj) { \
(obj)->_uiRef++; \ (obj)->_uiRef++; \
} }
#define is_delegable(t) (sq_type(t)&SQOBJECT_DELEGABLE) #define is_delegable(t) (sq_type(t)&SQOBJECT_DELEGABLE)
@ -170,146 +170,146 @@ struct SQObjectPtr;
#endif #endif
#define _REF_TYPE_DECL(type,_class,sym) \ #define _REF_TYPE_DECL(type,_class,sym) \
SQObjectPtr(_class * x) \ SQObjectPtr(_class * x) \
{ \ { \
SQ_OBJECT_RAWINIT() \ SQ_OBJECT_RAWINIT() \
_type=type; \ _type=type; \
_unVal.sym = x; \ _unVal.sym = x; \
assert(_unVal.pTable); \ assert(_unVal.pTable); \
_unVal.pRefCounted->_uiRef++; \ _unVal.pRefCounted->_uiRef++; \
} \ } \
inline SQObjectPtr& operator=(_class *x) \ inline SQObjectPtr& operator=(_class *x) \
{ \ { \
SQObjectType tOldType; \ SQObjectType tOldType; \
SQObjectValue unOldVal; \ SQObjectValue unOldVal; \
tOldType=_type; \ tOldType=_type; \
unOldVal=_unVal; \ unOldVal=_unVal; \
_type = type; \ _type = type; \
SQ_REFOBJECT_INIT() \ SQ_REFOBJECT_INIT() \
_unVal.sym = x; \ _unVal.sym = x; \
_unVal.pRefCounted->_uiRef++; \ _unVal.pRefCounted->_uiRef++; \
__Release(tOldType,unOldVal); \ __Release(tOldType,unOldVal); \
return *this; \ return *this; \
} }
#define _SCALAR_TYPE_DECL(type,_class,sym) \ #define _SCALAR_TYPE_DECL(type,_class,sym) \
SQObjectPtr(_class x) \ SQObjectPtr(_class x) \
{ \ { \
SQ_OBJECT_RAWINIT() \ SQ_OBJECT_RAWINIT() \
_type=type; \ _type=type; \
_unVal.sym = x; \ _unVal.sym = x; \
} \ } \
inline SQObjectPtr& operator=(_class x) \ inline SQObjectPtr& operator=(_class x) \
{ \ { \
__Release(_type,_unVal); \ __Release(_type,_unVal); \
_type = type; \ _type = type; \
SQ_OBJECT_RAWINIT() \ SQ_OBJECT_RAWINIT() \
_unVal.sym = x; \ _unVal.sym = x; \
return *this; \ return *this; \
} }
struct SQObjectPtr : public SQObject struct SQObjectPtr : public SQObject
{ {
SQObjectPtr() SQObjectPtr()
{ {
SQ_OBJECT_RAWINIT() SQ_OBJECT_RAWINIT()
_type=OT_NULL; _type=OT_NULL;
_unVal.pUserPointer=NULL; _unVal.pUserPointer=NULL;
} }
SQObjectPtr(const SQObjectPtr &o) SQObjectPtr(const SQObjectPtr &o)
{ {
_type = o._type; _type = o._type;
_unVal = o._unVal; _unVal = o._unVal;
__AddRef(_type,_unVal); __AddRef(_type,_unVal);
} }
SQObjectPtr(const SQObject &o) SQObjectPtr(const SQObject &o)
{ {
_type = o._type; _type = o._type;
_unVal = o._unVal; _unVal = o._unVal;
__AddRef(_type,_unVal); __AddRef(_type,_unVal);
} }
_REF_TYPE_DECL(OT_TABLE,SQTable,pTable) _REF_TYPE_DECL(OT_TABLE,SQTable,pTable)
_REF_TYPE_DECL(OT_CLASS,SQClass,pClass) _REF_TYPE_DECL(OT_CLASS,SQClass,pClass)
_REF_TYPE_DECL(OT_INSTANCE,SQInstance,pInstance) _REF_TYPE_DECL(OT_INSTANCE,SQInstance,pInstance)
_REF_TYPE_DECL(OT_ARRAY,SQArray,pArray) _REF_TYPE_DECL(OT_ARRAY,SQArray,pArray)
_REF_TYPE_DECL(OT_CLOSURE,SQClosure,pClosure) _REF_TYPE_DECL(OT_CLOSURE,SQClosure,pClosure)
_REF_TYPE_DECL(OT_NATIVECLOSURE,SQNativeClosure,pNativeClosure) _REF_TYPE_DECL(OT_NATIVECLOSURE,SQNativeClosure,pNativeClosure)
_REF_TYPE_DECL(OT_OUTER,SQOuter,pOuter) _REF_TYPE_DECL(OT_OUTER,SQOuter,pOuter)
_REF_TYPE_DECL(OT_GENERATOR,SQGenerator,pGenerator) _REF_TYPE_DECL(OT_GENERATOR,SQGenerator,pGenerator)
_REF_TYPE_DECL(OT_STRING,SQString,pString) _REF_TYPE_DECL(OT_STRING,SQString,pString)
_REF_TYPE_DECL(OT_USERDATA,SQUserData,pUserData) _REF_TYPE_DECL(OT_USERDATA,SQUserData,pUserData)
_REF_TYPE_DECL(OT_WEAKREF,SQWeakRef,pWeakRef) _REF_TYPE_DECL(OT_WEAKREF,SQWeakRef,pWeakRef)
_REF_TYPE_DECL(OT_THREAD,SQVM,pThread) _REF_TYPE_DECL(OT_THREAD,SQVM,pThread)
_REF_TYPE_DECL(OT_FUNCPROTO,SQFunctionProto,pFunctionProto) _REF_TYPE_DECL(OT_FUNCPROTO,SQFunctionProto,pFunctionProto)
_SCALAR_TYPE_DECL(OT_INTEGER,SQInteger,nInteger) _SCALAR_TYPE_DECL(OT_INTEGER,SQInteger,nInteger)
_SCALAR_TYPE_DECL(OT_FLOAT,SQFloat,fFloat) _SCALAR_TYPE_DECL(OT_FLOAT,SQFloat,fFloat)
_SCALAR_TYPE_DECL(OT_USERPOINTER,SQUserPointer,pUserPointer) _SCALAR_TYPE_DECL(OT_USERPOINTER,SQUserPointer,pUserPointer)
SQObjectPtr(bool bBool) SQObjectPtr(bool bBool)
{ {
SQ_OBJECT_RAWINIT() SQ_OBJECT_RAWINIT()
_type = OT_BOOL; _type = OT_BOOL;
_unVal.nInteger = bBool?1:0; _unVal.nInteger = bBool?1:0;
} }
inline SQObjectPtr& operator=(bool b) inline SQObjectPtr& operator=(bool b)
{ {
__Release(_type,_unVal); __Release(_type,_unVal);
SQ_OBJECT_RAWINIT() SQ_OBJECT_RAWINIT()
_type = OT_BOOL; _type = OT_BOOL;
_unVal.nInteger = b?1:0; _unVal.nInteger = b?1:0;
return *this; return *this;
} }
~SQObjectPtr() ~SQObjectPtr()
{ {
__Release(_type,_unVal); __Release(_type,_unVal);
} }
inline SQObjectPtr& operator=(const SQObjectPtr& obj) inline SQObjectPtr& operator=(const SQObjectPtr& obj)
{ {
SQObjectType tOldType; SQObjectType tOldType;
SQObjectValue unOldVal; SQObjectValue unOldVal;
tOldType=_type; tOldType=_type;
unOldVal=_unVal; unOldVal=_unVal;
_unVal = obj._unVal; _unVal = obj._unVal;
_type = obj._type; _type = obj._type;
__AddRef(_type,_unVal); __AddRef(_type,_unVal);
__Release(tOldType,unOldVal); __Release(tOldType,unOldVal);
return *this; return *this;
} }
inline SQObjectPtr& operator=(const SQObject& obj) inline SQObjectPtr& operator=(const SQObject& obj)
{ {
SQObjectType tOldType; SQObjectType tOldType;
SQObjectValue unOldVal; SQObjectValue unOldVal;
tOldType=_type; tOldType=_type;
unOldVal=_unVal; unOldVal=_unVal;
_unVal = obj._unVal; _unVal = obj._unVal;
_type = obj._type; _type = obj._type;
__AddRef(_type,_unVal); __AddRef(_type,_unVal);
__Release(tOldType,unOldVal); __Release(tOldType,unOldVal);
return *this; return *this;
} }
inline void Null() inline void Null()
{ {
SQObjectType tOldType = _type; SQObjectType tOldType = _type;
SQObjectValue unOldVal = _unVal; SQObjectValue unOldVal = _unVal;
_type = OT_NULL; _type = OT_NULL;
_unVal.raw = (SQRawObjectVal)NULL; _unVal.raw = (SQRawObjectVal)NULL;
__Release(tOldType ,unOldVal); __Release(tOldType ,unOldVal);
} }
private: private:
SQObjectPtr(const SQChar *){} //safety SQObjectPtr(const SQChar *){} //safety
}; };
inline void _Swap(SQObject &a,SQObject &b) inline void _Swap(SQObject &a,SQObject &b)
{ {
SQObjectType tOldType = a._type; SQObjectType tOldType = a._type;
SQObjectValue unOldVal = a._unVal; SQObjectValue unOldVal = a._unVal;
a._type = b._type; a._type = b._type;
a._unVal = b._unVal; a._unVal = b._unVal;
b._type = tOldType; b._type = tOldType;
b._unVal = unOldVal; b._unVal = unOldVal;
} }
#define ADD_TO_CHAIN(chain,obj) ((void)0) #define ADD_TO_CHAIN(chain,obj) ((void)0)
@ -318,9 +318,9 @@ inline void _Swap(SQObject &a,SQObject &b)
#define INIT_CHAIN() ((void)0) #define INIT_CHAIN() ((void)0)
struct SQDelegable : public CHAINABLE_OBJ { struct SQDelegable : public CHAINABLE_OBJ {
bool SetDelegate(SQTable *m); bool SetDelegate(SQTable *m);
virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res); virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
SQTable *_delegate; SQTable *_delegate;
}; };
SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx); SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx);

View File

@ -11,126 +11,126 @@
#define MAX_LITERALS ((SQInteger)0x7FFFFFFF) #define MAX_LITERALS ((SQInteger)0x7FFFFFFF)
enum BitWiseOP { enum BitWiseOP {
BW_AND = 0, BW_AND = 0,
BW_OR = 2, BW_OR = 2,
BW_XOR = 3, BW_XOR = 3,
BW_SHIFTL = 4, BW_SHIFTL = 4,
BW_SHIFTR = 5, BW_SHIFTR = 5,
BW_USHIFTR = 6 BW_USHIFTR = 6
}; };
enum CmpOP { enum CmpOP {
CMP_G = 0, CMP_G = 0,
CMP_GE = 2, CMP_GE = 2,
CMP_L = 3, CMP_L = 3,
CMP_LE = 4, CMP_LE = 4,
CMP_3W = 5 CMP_3W = 5
}; };
enum NewObjectType { enum NewObjectType {
NOT_TABLE = 0, NOT_TABLE = 0,
NOT_ARRAY = 1, NOT_ARRAY = 1,
NOT_CLASS = 2 NOT_CLASS = 2
}; };
enum AppendArrayType { enum AppendArrayType {
AAT_STACK = 0, AAT_STACK = 0,
AAT_LITERAL = 1, AAT_LITERAL = 1,
AAT_INT = 2, AAT_INT = 2,
AAT_FLOAT = 3, AAT_FLOAT = 3,
AAT_BOOL = 4 AAT_BOOL = 4
}; };
enum SQOpcode enum SQOpcode
{ {
_OP_LINE= 0x00, _OP_LINE= 0x00,
_OP_LOAD= 0x01, _OP_LOAD= 0x01,
_OP_LOADINT= 0x02, _OP_LOADINT= 0x02,
_OP_LOADFLOAT= 0x03, _OP_LOADFLOAT= 0x03,
_OP_DLOAD= 0x04, _OP_DLOAD= 0x04,
_OP_TAILCALL= 0x05, _OP_TAILCALL= 0x05,
_OP_CALL= 0x06, _OP_CALL= 0x06,
_OP_PREPCALL= 0x07, _OP_PREPCALL= 0x07,
_OP_PREPCALLK= 0x08, _OP_PREPCALLK= 0x08,
_OP_GETK= 0x09, _OP_GETK= 0x09,
_OP_MOVE= 0x0A, _OP_MOVE= 0x0A,
_OP_NEWSLOT= 0x0B, _OP_NEWSLOT= 0x0B,
_OP_DELETE= 0x0C, _OP_DELETE= 0x0C,
_OP_SET= 0x0D, _OP_SET= 0x0D,
_OP_GET= 0x0E, _OP_GET= 0x0E,
_OP_EQ= 0x0F, _OP_EQ= 0x0F,
_OP_NE= 0x10, _OP_NE= 0x10,
_OP_ADD= 0x11, _OP_ADD= 0x11,
_OP_SUB= 0x12, _OP_SUB= 0x12,
_OP_MUL= 0x13, _OP_MUL= 0x13,
_OP_DIV= 0x14, _OP_DIV= 0x14,
_OP_MOD= 0x15, _OP_MOD= 0x15,
_OP_BITW= 0x16, _OP_BITW= 0x16,
_OP_RETURN= 0x17, _OP_RETURN= 0x17,
_OP_LOADNULLS= 0x18, _OP_LOADNULLS= 0x18,
_OP_LOADROOT= 0x19, _OP_LOADROOT= 0x19,
_OP_LOADBOOL= 0x1A, _OP_LOADBOOL= 0x1A,
_OP_DMOVE= 0x1B, _OP_DMOVE= 0x1B,
_OP_JMP= 0x1C, _OP_JMP= 0x1C,
//_OP_JNZ= 0x1D, //_OP_JNZ= 0x1D,
_OP_JCMP= 0x1D, _OP_JCMP= 0x1D,
_OP_JZ= 0x1E, _OP_JZ= 0x1E,
_OP_SETOUTER= 0x1F, _OP_SETOUTER= 0x1F,
_OP_GETOUTER= 0x20, _OP_GETOUTER= 0x20,
_OP_NEWOBJ= 0x21, _OP_NEWOBJ= 0x21,
_OP_APPENDARRAY= 0x22, _OP_APPENDARRAY= 0x22,
_OP_COMPARITH= 0x23, _OP_COMPARITH= 0x23,
_OP_INC= 0x24, _OP_INC= 0x24,
_OP_INCL= 0x25, _OP_INCL= 0x25,
_OP_PINC= 0x26, _OP_PINC= 0x26,
_OP_PINCL= 0x27, _OP_PINCL= 0x27,
_OP_CMP= 0x28, _OP_CMP= 0x28,
_OP_EXISTS= 0x29, _OP_EXISTS= 0x29,
_OP_INSTANCEOF= 0x2A, _OP_INSTANCEOF= 0x2A,
_OP_AND= 0x2B, _OP_AND= 0x2B,
_OP_OR= 0x2C, _OP_OR= 0x2C,
_OP_NEG= 0x2D, _OP_NEG= 0x2D,
_OP_NOT= 0x2E, _OP_NOT= 0x2E,
_OP_BWNOT= 0x2F, _OP_BWNOT= 0x2F,
_OP_CLOSURE= 0x30, _OP_CLOSURE= 0x30,
_OP_YIELD= 0x31, _OP_YIELD= 0x31,
_OP_RESUME= 0x32, _OP_RESUME= 0x32,
_OP_FOREACH= 0x33, _OP_FOREACH= 0x33,
_OP_POSTFOREACH= 0x34, _OP_POSTFOREACH= 0x34,
_OP_CLONE= 0x35, _OP_CLONE= 0x35,
_OP_TYPEOF= 0x36, _OP_TYPEOF= 0x36,
_OP_PUSHTRAP= 0x37, _OP_PUSHTRAP= 0x37,
_OP_POPTRAP= 0x38, _OP_POPTRAP= 0x38,
_OP_THROW= 0x39, _OP_THROW= 0x39,
_OP_NEWSLOTA= 0x3A, _OP_NEWSLOTA= 0x3A,
_OP_GETBASE= 0x3B, _OP_GETBASE= 0x3B,
_OP_CLOSE= 0x3C _OP_CLOSE= 0x3C
}; };
struct SQInstructionDesc { struct SQInstructionDesc {
const SQChar *name; const SQChar *name;
}; };
struct SQInstruction struct SQInstruction
{ {
SQInstruction(){}; SQInstruction(){};
SQInstruction(SQOpcode _op,SQInteger a0=0,SQInteger a1=0,SQInteger a2=0,SQInteger a3=0) SQInstruction(SQOpcode _op,SQInteger a0=0,SQInteger a1=0,SQInteger a2=0,SQInteger a3=0)
{ op = (unsigned char)_op; { op = (unsigned char)_op;
_arg0 = (unsigned char)a0;_arg1 = (SQInt32)a1; _arg0 = (unsigned char)a0;_arg1 = (SQInt32)a1;
_arg2 = (unsigned char)a2;_arg3 = (unsigned char)a3; _arg2 = (unsigned char)a2;_arg3 = (unsigned char)a3;
} }
SQInt32 _arg1; SQInt32 _arg1;
unsigned char op; unsigned char op;
unsigned char _arg0; unsigned char _arg0;
unsigned char _arg2; unsigned char _arg2;
unsigned char _arg3; unsigned char _arg3;
}; };
#include <rabbit/squtils.hpp> #include <rabbit/squtils.hpp>
typedef sqvector<SQInstruction> SQInstructionVec; typedef sqvector<SQInstruction> SQInstructionVec;
#define NEW_SLOT_ATTRIBUTES_FLAG 0x01 #define NEW_SLOT_ATTRIBUTES_FLAG 0x01
#define NEW_SLOT_STATIC_FLAG 0x02 #define NEW_SLOT_STATIC_FLAG 0x02

View File

@ -18,356 +18,356 @@
SQSharedState::SQSharedState() SQSharedState::SQSharedState()
{ {
_compilererrorhandler = NULL; _compilererrorhandler = NULL;
_printfunc = NULL; _printfunc = NULL;
_errorfunc = NULL; _errorfunc = NULL;
_debuginfo = false; _debuginfo = false;
_notifyallexceptions = false; _notifyallexceptions = false;
_foreignptr = NULL; _foreignptr = NULL;
_releasehook = NULL; _releasehook = NULL;
} }
#define newsysstring(s) { \ #define newsysstring(s) { \
_systemstrings->push_back(SQString::Create(this,s)); \ _systemstrings->push_back(SQString::Create(this,s)); \
} }
#define newmetamethod(s) { \ #define newmetamethod(s) { \
_metamethods->push_back(SQString::Create(this,s)); \ _metamethods->push_back(SQString::Create(this,s)); \
_table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \ _table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \
} }
bool CompileTypemask(SQIntVec &res,const SQChar *typemask) bool CompileTypemask(SQIntVec &res,const SQChar *typemask)
{ {
SQInteger i = 0; SQInteger i = 0;
SQInteger mask = 0; SQInteger mask = 0;
while(typemask[i] != 0) { while(typemask[i] != 0) {
switch(typemask[i]) { switch(typemask[i]) {
case 'o': mask |= _RT_NULL; break; case 'o': mask |= _RT_NULL; break;
case 'i': mask |= _RT_INTEGER; break; case 'i': mask |= _RT_INTEGER; break;
case 'f': mask |= _RT_FLOAT; break; case 'f': mask |= _RT_FLOAT; break;
case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break; case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break;
case 's': mask |= _RT_STRING; break; case 's': mask |= _RT_STRING; break;
case 't': mask |= _RT_TABLE; break; case 't': mask |= _RT_TABLE; break;
case 'a': mask |= _RT_ARRAY; break; case 'a': mask |= _RT_ARRAY; break;
case 'u': mask |= _RT_USERDATA; break; case 'u': mask |= _RT_USERDATA; break;
case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break; case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break;
case 'b': mask |= _RT_BOOL; break; case 'b': mask |= _RT_BOOL; break;
case 'g': mask |= _RT_GENERATOR; break; case 'g': mask |= _RT_GENERATOR; break;
case 'p': mask |= _RT_USERPOINTER; break; case 'p': mask |= _RT_USERPOINTER; break;
case 'v': mask |= _RT_THREAD; break; case 'v': mask |= _RT_THREAD; break;
case 'x': mask |= _RT_INSTANCE; break; case 'x': mask |= _RT_INSTANCE; break;
case 'y': mask |= _RT_CLASS; break; case 'y': mask |= _RT_CLASS; break;
case 'r': mask |= _RT_WEAKREF; break; case 'r': mask |= _RT_WEAKREF; break;
case '.': mask = -1; res.push_back(mask); i++; mask = 0; continue; case '.': mask = -1; res.push_back(mask); i++; mask = 0; continue;
case ' ': i++; continue; //ignores spaces case ' ': i++; continue; //ignores spaces
default: default:
return false; return false;
} }
i++; i++;
if(typemask[i] == '|') { if(typemask[i] == '|') {
i++; i++;
if(typemask[i] == 0) if(typemask[i] == 0)
return false; return false;
continue; continue;
} }
res.push_back(mask); res.push_back(mask);
mask = 0; mask = 0;
} }
return true; return true;
} }
SQTable *CreateDefaultDelegate(SQSharedState *ss,const SQRegFunction *funcz) SQTable *CreateDefaultDelegate(SQSharedState *ss,const SQRegFunction *funcz)
{ {
SQInteger i=0; SQInteger i=0;
SQTable *t=SQTable::Create(ss,0); SQTable *t=SQTable::Create(ss,0);
while(funcz[i].name!=0){ while(funcz[i].name!=0){
SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f,0); SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f,0);
nc->_nparamscheck = funcz[i].nparamscheck; nc->_nparamscheck = funcz[i].nparamscheck;
nc->_name = SQString::Create(ss,funcz[i].name); nc->_name = SQString::Create(ss,funcz[i].name);
if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask)) if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask))
return NULL; return NULL;
t->NewSlot(SQString::Create(ss,funcz[i].name),nc); t->NewSlot(SQString::Create(ss,funcz[i].name),nc);
i++; i++;
} }
return t; return t;
} }
void SQSharedState::Init() void SQSharedState::Init()
{ {
_scratchpad=NULL; _scratchpad=NULL;
_scratchpadsize=0; _scratchpadsize=0;
_stringtable = (SQStringTable*)SQ_MALLOC(sizeof(SQStringTable)); _stringtable = (SQStringTable*)SQ_MALLOC(sizeof(SQStringTable));
new (_stringtable) SQStringTable(this); new (_stringtable) SQStringTable(this);
sq_new(_metamethods,SQObjectPtrVec); sq_new(_metamethods,SQObjectPtrVec);
sq_new(_systemstrings,SQObjectPtrVec); sq_new(_systemstrings,SQObjectPtrVec);
sq_new(_types,SQObjectPtrVec); sq_new(_types,SQObjectPtrVec);
_metamethodsmap = SQTable::Create(this,MT_LAST-1); _metamethodsmap = SQTable::Create(this,MT_LAST-1);
//adding type strings to avoid memory trashing //adding type strings to avoid memory trashing
//types names //types names
newsysstring(_SC("null")); newsysstring(_SC("null"));
newsysstring(_SC("table")); newsysstring(_SC("table"));
newsysstring(_SC("array")); newsysstring(_SC("array"));
newsysstring(_SC("closure")); newsysstring(_SC("closure"));
newsysstring(_SC("string")); newsysstring(_SC("string"));
newsysstring(_SC("userdata")); newsysstring(_SC("userdata"));
newsysstring(_SC("integer")); newsysstring(_SC("integer"));
newsysstring(_SC("float")); newsysstring(_SC("float"));
newsysstring(_SC("userpointer")); newsysstring(_SC("userpointer"));
newsysstring(_SC("function")); newsysstring(_SC("function"));
newsysstring(_SC("generator")); newsysstring(_SC("generator"));
newsysstring(_SC("thread")); newsysstring(_SC("thread"));
newsysstring(_SC("class")); newsysstring(_SC("class"));
newsysstring(_SC("instance")); newsysstring(_SC("instance"));
newsysstring(_SC("bool")); newsysstring(_SC("bool"));
//meta methods //meta methods
newmetamethod(MM_ADD); newmetamethod(MM_ADD);
newmetamethod(MM_SUB); newmetamethod(MM_SUB);
newmetamethod(MM_MUL); newmetamethod(MM_MUL);
newmetamethod(MM_DIV); newmetamethod(MM_DIV);
newmetamethod(MM_UNM); newmetamethod(MM_UNM);
newmetamethod(MM_MODULO); newmetamethod(MM_MODULO);
newmetamethod(MM_SET); newmetamethod(MM_SET);
newmetamethod(MM_GET); newmetamethod(MM_GET);
newmetamethod(MM_TYPEOF); newmetamethod(MM_TYPEOF);
newmetamethod(MM_NEXTI); newmetamethod(MM_NEXTI);
newmetamethod(MM_CMP); newmetamethod(MM_CMP);
newmetamethod(MM_CALL); newmetamethod(MM_CALL);
newmetamethod(MM_CLONED); newmetamethod(MM_CLONED);
newmetamethod(MM_NEWSLOT); newmetamethod(MM_NEWSLOT);
newmetamethod(MM_DELSLOT); newmetamethod(MM_DELSLOT);
newmetamethod(MM_TOSTRING); newmetamethod(MM_TOSTRING);
newmetamethod(MM_NEWMEMBER); newmetamethod(MM_NEWMEMBER);
newmetamethod(MM_INHERITED); newmetamethod(MM_INHERITED);
_constructoridx = SQString::Create(this,_SC("constructor")); _constructoridx = SQString::Create(this,_SC("constructor"));
_registry = SQTable::Create(this,0); _registry = SQTable::Create(this,0);
_consts = SQTable::Create(this,0); _consts = SQTable::Create(this,0);
_table_default_delegate = CreateDefaultDelegate(this,_table_default_delegate_funcz); _table_default_delegate = CreateDefaultDelegate(this,_table_default_delegate_funcz);
_array_default_delegate = CreateDefaultDelegate(this,_array_default_delegate_funcz); _array_default_delegate = CreateDefaultDelegate(this,_array_default_delegate_funcz);
_string_default_delegate = CreateDefaultDelegate(this,_string_default_delegate_funcz); _string_default_delegate = CreateDefaultDelegate(this,_string_default_delegate_funcz);
_number_default_delegate = CreateDefaultDelegate(this,_number_default_delegate_funcz); _number_default_delegate = CreateDefaultDelegate(this,_number_default_delegate_funcz);
_closure_default_delegate = CreateDefaultDelegate(this,_closure_default_delegate_funcz); _closure_default_delegate = CreateDefaultDelegate(this,_closure_default_delegate_funcz);
_generator_default_delegate = CreateDefaultDelegate(this,_generator_default_delegate_funcz); _generator_default_delegate = CreateDefaultDelegate(this,_generator_default_delegate_funcz);
_thread_default_delegate = CreateDefaultDelegate(this,_thread_default_delegate_funcz); _thread_default_delegate = CreateDefaultDelegate(this,_thread_default_delegate_funcz);
_class_default_delegate = CreateDefaultDelegate(this,_class_default_delegate_funcz); _class_default_delegate = CreateDefaultDelegate(this,_class_default_delegate_funcz);
_instance_default_delegate = CreateDefaultDelegate(this,_instance_default_delegate_funcz); _instance_default_delegate = CreateDefaultDelegate(this,_instance_default_delegate_funcz);
_weakref_default_delegate = CreateDefaultDelegate(this,_weakref_default_delegate_funcz); _weakref_default_delegate = CreateDefaultDelegate(this,_weakref_default_delegate_funcz);
} }
SQSharedState::~SQSharedState() SQSharedState::~SQSharedState()
{ {
if(_releasehook) { _releasehook(_foreignptr,0); _releasehook = NULL; } if(_releasehook) { _releasehook(_foreignptr,0); _releasehook = NULL; }
_constructoridx.Null(); _constructoridx.Null();
_table(_registry)->Finalize(); _table(_registry)->Finalize();
_table(_consts)->Finalize(); _table(_consts)->Finalize();
_table(_metamethodsmap)->Finalize(); _table(_metamethodsmap)->Finalize();
_registry.Null(); _registry.Null();
_consts.Null(); _consts.Null();
_metamethodsmap.Null(); _metamethodsmap.Null();
while(!_systemstrings->empty()) { while(!_systemstrings->empty()) {
_systemstrings->back().Null(); _systemstrings->back().Null();
_systemstrings->pop_back(); _systemstrings->pop_back();
} }
_thread(_root_vm)->Finalize(); _thread(_root_vm)->Finalize();
_root_vm.Null(); _root_vm.Null();
_table_default_delegate.Null(); _table_default_delegate.Null();
_array_default_delegate.Null(); _array_default_delegate.Null();
_string_default_delegate.Null(); _string_default_delegate.Null();
_number_default_delegate.Null(); _number_default_delegate.Null();
_closure_default_delegate.Null(); _closure_default_delegate.Null();
_generator_default_delegate.Null(); _generator_default_delegate.Null();
_thread_default_delegate.Null(); _thread_default_delegate.Null();
_class_default_delegate.Null(); _class_default_delegate.Null();
_instance_default_delegate.Null(); _instance_default_delegate.Null();
_weakref_default_delegate.Null(); _weakref_default_delegate.Null();
_refs_table.Finalize(); _refs_table.Finalize();
sq_delete(_types,SQObjectPtrVec); sq_delete(_types,SQObjectPtrVec);
sq_delete(_systemstrings,SQObjectPtrVec); sq_delete(_systemstrings,SQObjectPtrVec);
sq_delete(_metamethods,SQObjectPtrVec); sq_delete(_metamethods,SQObjectPtrVec);
sq_delete(_stringtable,SQStringTable); sq_delete(_stringtable,SQStringTable);
if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize); if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize);
} }
SQInteger SQSharedState::GetMetaMethodIdxByName(const SQObjectPtr &name) SQInteger SQSharedState::GetMetaMethodIdxByName(const SQObjectPtr &name)
{ {
if(sq_type(name) != OT_STRING) if(sq_type(name) != OT_STRING)
return -1; return -1;
SQObjectPtr ret; SQObjectPtr ret;
if(_table(_metamethodsmap)->Get(name,ret)) { if(_table(_metamethodsmap)->Get(name,ret)) {
return _integer(ret); return _integer(ret);
} }
return -1; return -1;
} }
SQChar* SQSharedState::GetScratchPad(SQInteger size) SQChar* SQSharedState::GetScratchPad(SQInteger size)
{ {
SQInteger newsize; SQInteger newsize;
if(size>0) { if(size>0) {
if(_scratchpadsize < size) { if(_scratchpadsize < size) {
newsize = size + (size>>1); newsize = size + (size>>1);
_scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
_scratchpadsize = newsize; _scratchpadsize = newsize;
}else if(_scratchpadsize >= (size<<5)) { }else if(_scratchpadsize >= (size<<5)) {
newsize = _scratchpadsize >> 1; newsize = _scratchpadsize >> 1;
_scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
_scratchpadsize = newsize; _scratchpadsize = newsize;
} }
} }
return _scratchpad; return _scratchpad;
} }
RefTable::RefTable() RefTable::RefTable()
{ {
AllocNodes(4); AllocNodes(4);
} }
void RefTable::Finalize() void RefTable::Finalize()
{ {
RefNode *nodes = _nodes; RefNode *nodes = _nodes;
for(SQUnsignedInteger n = 0; n < _numofslots; n++) { for(SQUnsignedInteger n = 0; n < _numofslots; n++) {
nodes->obj.Null(); nodes->obj.Null();
nodes++; nodes++;
} }
} }
RefTable::~RefTable() RefTable::~RefTable()
{ {
SQ_FREE(_buckets,(_numofslots * sizeof(RefNode *)) + (_numofslots * sizeof(RefNode))); SQ_FREE(_buckets,(_numofslots * sizeof(RefNode *)) + (_numofslots * sizeof(RefNode)));
} }
void RefTable::AddRef(SQObject &obj) void RefTable::AddRef(SQObject &obj)
{ {
SQHash mainpos; SQHash mainpos;
RefNode *prev; RefNode *prev;
RefNode *ref = Get(obj,mainpos,&prev,true); RefNode *ref = Get(obj,mainpos,&prev,true);
ref->refs++; ref->refs++;
} }
SQUnsignedInteger RefTable::GetRefCount(SQObject &obj) SQUnsignedInteger RefTable::GetRefCount(SQObject &obj)
{ {
SQHash mainpos; SQHash mainpos;
RefNode *prev; RefNode *prev;
RefNode *ref = Get(obj,mainpos,&prev,true); RefNode *ref = Get(obj,mainpos,&prev,true);
return ref->refs; return ref->refs;
} }
SQBool RefTable::Release(SQObject &obj) SQBool RefTable::Release(SQObject &obj)
{ {
SQHash mainpos; SQHash mainpos;
RefNode *prev; RefNode *prev;
RefNode *ref = Get(obj,mainpos,&prev,false); RefNode *ref = Get(obj,mainpos,&prev,false);
if(ref) { if(ref) {
if(--ref->refs == 0) { if(--ref->refs == 0) {
SQObjectPtr o = ref->obj; SQObjectPtr o = ref->obj;
if(prev) { if(prev) {
prev->next = ref->next; prev->next = ref->next;
} }
else { else {
_buckets[mainpos] = ref->next; _buckets[mainpos] = ref->next;
} }
ref->next = _freelist; ref->next = _freelist;
_freelist = ref; _freelist = ref;
_slotused--; _slotused--;
ref->obj.Null(); ref->obj.Null();
//<<FIXME>>test for shrink? //<<FIXME>>test for shrink?
return SQTrue; return SQTrue;
} }
} }
else { else {
assert(0); assert(0);
} }
return SQFalse; return SQFalse;
} }
void RefTable::Resize(SQUnsignedInteger size) void RefTable::Resize(SQUnsignedInteger size)
{ {
RefNode **oldbucks = _buckets; RefNode **oldbucks = _buckets;
RefNode *t = _nodes; RefNode *t = _nodes;
SQUnsignedInteger oldnumofslots = _numofslots; SQUnsignedInteger oldnumofslots = _numofslots;
AllocNodes(size); AllocNodes(size);
//rehash //rehash
SQUnsignedInteger nfound = 0; SQUnsignedInteger nfound = 0;
for(SQUnsignedInteger n = 0; n < oldnumofslots; n++) { for(SQUnsignedInteger n = 0; n < oldnumofslots; n++) {
if(sq_type(t->obj) != OT_NULL) { if(sq_type(t->obj) != OT_NULL) {
//add back; //add back;
assert(t->refs != 0); assert(t->refs != 0);
RefNode *nn = Add(::HashObj(t->obj)&(_numofslots-1),t->obj); RefNode *nn = Add(::HashObj(t->obj)&(_numofslots-1),t->obj);
nn->refs = t->refs; nn->refs = t->refs;
t->obj.Null(); t->obj.Null();
nfound++; nfound++;
} }
t++; t++;
} }
assert(nfound == oldnumofslots); assert(nfound == oldnumofslots);
SQ_FREE(oldbucks,(oldnumofslots * sizeof(RefNode *)) + (oldnumofslots * sizeof(RefNode))); SQ_FREE(oldbucks,(oldnumofslots * sizeof(RefNode *)) + (oldnumofslots * sizeof(RefNode)));
} }
RefTable::RefNode *RefTable::Add(SQHash mainpos,SQObject &obj) RefTable::RefNode *RefTable::Add(SQHash mainpos,SQObject &obj)
{ {
RefNode *t = _buckets[mainpos]; RefNode *t = _buckets[mainpos];
RefNode *newnode = _freelist; RefNode *newnode = _freelist;
newnode->obj = obj; newnode->obj = obj;
_buckets[mainpos] = newnode; _buckets[mainpos] = newnode;
_freelist = _freelist->next; _freelist = _freelist->next;
newnode->next = t; newnode->next = t;
assert(newnode->refs == 0); assert(newnode->refs == 0);
_slotused++; _slotused++;
return newnode; return newnode;
} }
RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add) RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add)
{ {
RefNode *ref; RefNode *ref;
mainpos = ::HashObj(obj)&(_numofslots-1); mainpos = ::HashObj(obj)&(_numofslots-1);
*prev = NULL; *prev = NULL;
for (ref = _buckets[mainpos]; ref; ) { for (ref = _buckets[mainpos]; ref; ) {
if(_rawval(ref->obj) == _rawval(obj) && sq_type(ref->obj) == sq_type(obj)) if(_rawval(ref->obj) == _rawval(obj) && sq_type(ref->obj) == sq_type(obj))
break; break;
*prev = ref; *prev = ref;
ref = ref->next; ref = ref->next;
} }
if(ref == NULL && add) { if(ref == NULL && add) {
if(_numofslots == _slotused) { if(_numofslots == _slotused) {
assert(_freelist == 0); assert(_freelist == 0);
Resize(_numofslots*2); Resize(_numofslots*2);
mainpos = ::HashObj(obj)&(_numofslots-1); mainpos = ::HashObj(obj)&(_numofslots-1);
} }
ref = Add(mainpos,obj); ref = Add(mainpos,obj);
} }
return ref; return ref;
} }
void RefTable::AllocNodes(SQUnsignedInteger size) void RefTable::AllocNodes(SQUnsignedInteger size)
{ {
RefNode **bucks; RefNode **bucks;
RefNode *nodes; RefNode *nodes;
bucks = (RefNode **)SQ_MALLOC((size * sizeof(RefNode *)) + (size * sizeof(RefNode))); bucks = (RefNode **)SQ_MALLOC((size * sizeof(RefNode *)) + (size * sizeof(RefNode)));
nodes = (RefNode *)&bucks[size]; nodes = (RefNode *)&bucks[size];
RefNode *temp = nodes; RefNode *temp = nodes;
SQUnsignedInteger n; SQUnsignedInteger n;
for(n = 0; n < size - 1; n++) { for(n = 0; n < size - 1; n++) {
bucks[n] = NULL; bucks[n] = NULL;
temp->refs = 0; temp->refs = 0;
new (&temp->obj) SQObjectPtr; new (&temp->obj) SQObjectPtr;
temp->next = temp+1; temp->next = temp+1;
temp++; temp++;
} }
bucks[n] = NULL; bucks[n] = NULL;
temp->refs = 0; temp->refs = 0;
new (&temp->obj) SQObjectPtr; new (&temp->obj) SQObjectPtr;
temp->next = NULL; temp->next = NULL;
_freelist = nodes; _freelist = nodes;
_nodes = nodes; _nodes = nodes;
_buckets = bucks; _buckets = bucks;
_slotused = 0; _slotused = 0;
_numofslots = size; _numofslots = size;
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
//SQStringTable //SQStringTable
@ -379,89 +379,89 @@ void RefTable::AllocNodes(SQUnsignedInteger size)
SQStringTable::SQStringTable(SQSharedState *ss) SQStringTable::SQStringTable(SQSharedState *ss)
{ {
_sharedstate = ss; _sharedstate = ss;
AllocNodes(4); AllocNodes(4);
_slotused = 0; _slotused = 0;
} }
SQStringTable::~SQStringTable() SQStringTable::~SQStringTable()
{ {
SQ_FREE(_strings,sizeof(SQString*)*_numofslots); SQ_FREE(_strings,sizeof(SQString*)*_numofslots);
_strings = NULL; _strings = NULL;
} }
void SQStringTable::AllocNodes(SQInteger size) void SQStringTable::AllocNodes(SQInteger size)
{ {
_numofslots = size; _numofslots = size;
_strings = (SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots); _strings = (SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots);
memset(_strings,0,sizeof(SQString*)*_numofslots); memset(_strings,0,sizeof(SQString*)*_numofslots);
} }
SQString *SQStringTable::Add(const SQChar *news,SQInteger len) SQString *SQStringTable::Add(const SQChar *news,SQInteger len)
{ {
if(len<0) if(len<0)
len = (SQInteger)scstrlen(news); len = (SQInteger)scstrlen(news);
SQHash newhash = ::_hashstr(news,len); SQHash newhash = ::_hashstr(news,len);
SQHash h = newhash&(_numofslots-1); SQHash h = newhash&(_numofslots-1);
SQString *s; SQString *s;
for (s = _strings[h]; s; s = s->_next){ for (s = _strings[h]; s; s = s->_next){
if(s->_len == len && (!memcmp(news,s->_val,sq_rsl(len)))) if(s->_len == len && (!memcmp(news,s->_val,sq_rsl(len))))
return s; //found return s; //found
} }
SQString *t = (SQString *)SQ_MALLOC(sq_rsl(len)+sizeof(SQString)); SQString *t = (SQString *)SQ_MALLOC(sq_rsl(len)+sizeof(SQString));
new (t) SQString; new (t) SQString;
t->_sharedstate = _sharedstate; t->_sharedstate = _sharedstate;
memcpy(t->_val,news,sq_rsl(len)); memcpy(t->_val,news,sq_rsl(len));
t->_val[len] = _SC('\0'); t->_val[len] = _SC('\0');
t->_len = len; t->_len = len;
t->_hash = newhash; t->_hash = newhash;
t->_next = _strings[h]; t->_next = _strings[h];
_strings[h] = t; _strings[h] = t;
_slotused++; _slotused++;
if (_slotused > _numofslots) /* too crowded? */ if (_slotused > _numofslots) /* too crowded? */
Resize(_numofslots*2); Resize(_numofslots*2);
return t; return t;
} }
void SQStringTable::Resize(SQInteger size) void SQStringTable::Resize(SQInteger size)
{ {
SQInteger oldsize=_numofslots; SQInteger oldsize=_numofslots;
SQString **oldtable=_strings; SQString **oldtable=_strings;
AllocNodes(size); AllocNodes(size);
for (SQInteger i=0; i<oldsize; i++){ for (SQInteger i=0; i<oldsize; i++){
SQString *p = oldtable[i]; SQString *p = oldtable[i];
while(p){ while(p){
SQString *next = p->_next; SQString *next = p->_next;
SQHash h = p->_hash&(_numofslots-1); SQHash h = p->_hash&(_numofslots-1);
p->_next = _strings[h]; p->_next = _strings[h];
_strings[h] = p; _strings[h] = p;
p = next; p = next;
} }
} }
SQ_FREE(oldtable,oldsize*sizeof(SQString*)); SQ_FREE(oldtable,oldsize*sizeof(SQString*));
} }
void SQStringTable::Remove(SQString *bs) void SQStringTable::Remove(SQString *bs)
{ {
SQString *s; SQString *s;
SQString *prev=NULL; SQString *prev=NULL;
SQHash h = bs->_hash&(_numofslots - 1); SQHash h = bs->_hash&(_numofslots - 1);
for (s = _strings[h]; s; ){ for (s = _strings[h]; s; ){
if(s == bs){ if(s == bs){
if(prev) if(prev)
prev->_next = s->_next; prev->_next = s->_next;
else else
_strings[h] = s->_next; _strings[h] = s->_next;
_slotused--; _slotused--;
SQInteger slen = s->_len; SQInteger slen = s->_len;
s->~SQString(); s->~SQString();
SQ_FREE(s,sizeof(SQString) + sq_rsl(slen)); SQ_FREE(s,sizeof(SQString) + sq_rsl(slen));
return; return;
} }
prev = s; prev = s;
s = s->_next; s = s->_next;
} }
assert(0);//if this fail something is wrong assert(0);//if this fail something is wrong
} }

View File

@ -16,41 +16,41 @@ struct SQTable;
struct SQStringTable struct SQStringTable
{ {
SQStringTable(SQSharedState*ss); SQStringTable(SQSharedState*ss);
~SQStringTable(); ~SQStringTable();
SQString *Add(const SQChar *,SQInteger len); SQString *Add(const SQChar *,SQInteger len);
void Remove(SQString *); void Remove(SQString *);
private: private:
void Resize(SQInteger size); void Resize(SQInteger size);
void AllocNodes(SQInteger size); void AllocNodes(SQInteger size);
SQString **_strings; SQString **_strings;
SQUnsignedInteger _numofslots; SQUnsignedInteger _numofslots;
SQUnsignedInteger _slotused; SQUnsignedInteger _slotused;
SQSharedState *_sharedstate; SQSharedState *_sharedstate;
}; };
struct RefTable { struct RefTable {
struct RefNode { struct RefNode {
SQObjectPtr obj; SQObjectPtr obj;
SQUnsignedInteger refs; SQUnsignedInteger refs;
struct RefNode *next; struct RefNode *next;
}; };
RefTable(); RefTable();
~RefTable(); ~RefTable();
void AddRef(SQObject &obj); void AddRef(SQObject &obj);
SQBool Release(SQObject &obj); SQBool Release(SQObject &obj);
SQUnsignedInteger GetRefCount(SQObject &obj); SQUnsignedInteger GetRefCount(SQObject &obj);
void Finalize(); void Finalize();
private: private:
RefNode *Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add); RefNode *Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add);
RefNode *Add(SQHash mainpos,SQObject &obj); RefNode *Add(SQHash mainpos,SQObject &obj);
void Resize(SQUnsignedInteger size); void Resize(SQUnsignedInteger size);
void AllocNodes(SQUnsignedInteger size); void AllocNodes(SQUnsignedInteger size);
SQUnsignedInteger _numofslots; SQUnsignedInteger _numofslots;
SQUnsignedInteger _slotused; SQUnsignedInteger _slotused;
RefNode *_nodes; RefNode *_nodes;
RefNode *_freelist; RefNode *_freelist;
RefNode **_buckets; RefNode **_buckets;
}; };
#define ADD_STRING(ss,str,len) ss->_stringtable->Add(str,len) #define ADD_STRING(ss,str,len) ss->_stringtable->Add(str,len)
@ -60,66 +60,66 @@ struct SQObjectPtr;
struct SQSharedState struct SQSharedState
{ {
SQSharedState(); SQSharedState();
~SQSharedState(); ~SQSharedState();
void Init(); void Init();
public: public:
SQChar* GetScratchPad(SQInteger size); SQChar* GetScratchPad(SQInteger size);
SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name); SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name);
SQObjectPtrVec *_metamethods; SQObjectPtrVec *_metamethods;
SQObjectPtr _metamethodsmap; SQObjectPtr _metamethodsmap;
SQObjectPtrVec *_systemstrings; SQObjectPtrVec *_systemstrings;
SQObjectPtrVec *_types; SQObjectPtrVec *_types;
SQStringTable *_stringtable; SQStringTable *_stringtable;
RefTable _refs_table; RefTable _refs_table;
SQObjectPtr _registry; SQObjectPtr _registry;
SQObjectPtr _consts; SQObjectPtr _consts;
SQObjectPtr _constructoridx; SQObjectPtr _constructoridx;
SQObjectPtr _root_vm; SQObjectPtr _root_vm;
SQObjectPtr _table_default_delegate; SQObjectPtr _table_default_delegate;
static const SQRegFunction _table_default_delegate_funcz[]; static const SQRegFunction _table_default_delegate_funcz[];
SQObjectPtr _array_default_delegate; SQObjectPtr _array_default_delegate;
static const SQRegFunction _array_default_delegate_funcz[]; static const SQRegFunction _array_default_delegate_funcz[];
SQObjectPtr _string_default_delegate; SQObjectPtr _string_default_delegate;
static const SQRegFunction _string_default_delegate_funcz[]; static const SQRegFunction _string_default_delegate_funcz[];
SQObjectPtr _number_default_delegate; SQObjectPtr _number_default_delegate;
static const SQRegFunction _number_default_delegate_funcz[]; static const SQRegFunction _number_default_delegate_funcz[];
SQObjectPtr _generator_default_delegate; SQObjectPtr _generator_default_delegate;
static const SQRegFunction _generator_default_delegate_funcz[]; static const SQRegFunction _generator_default_delegate_funcz[];
SQObjectPtr _closure_default_delegate; SQObjectPtr _closure_default_delegate;
static const SQRegFunction _closure_default_delegate_funcz[]; static const SQRegFunction _closure_default_delegate_funcz[];
SQObjectPtr _thread_default_delegate; SQObjectPtr _thread_default_delegate;
static const SQRegFunction _thread_default_delegate_funcz[]; static const SQRegFunction _thread_default_delegate_funcz[];
SQObjectPtr _class_default_delegate; SQObjectPtr _class_default_delegate;
static const SQRegFunction _class_default_delegate_funcz[]; static const SQRegFunction _class_default_delegate_funcz[];
SQObjectPtr _instance_default_delegate; SQObjectPtr _instance_default_delegate;
static const SQRegFunction _instance_default_delegate_funcz[]; static const SQRegFunction _instance_default_delegate_funcz[];
SQObjectPtr _weakref_default_delegate; SQObjectPtr _weakref_default_delegate;
static const SQRegFunction _weakref_default_delegate_funcz[]; static const SQRegFunction _weakref_default_delegate_funcz[];
SQCOMPILERERROR _compilererrorhandler; SQCOMPILERERROR _compilererrorhandler;
SQPRINTFUNCTION _printfunc; SQPRINTFUNCTION _printfunc;
SQPRINTFUNCTION _errorfunc; SQPRINTFUNCTION _errorfunc;
bool _debuginfo; bool _debuginfo;
bool _notifyallexceptions; bool _notifyallexceptions;
SQUserPointer _foreignptr; SQUserPointer _foreignptr;
SQRELEASEHOOK _releasehook; SQRELEASEHOOK _releasehook;
private: private:
SQChar *_scratchpad; SQChar *_scratchpad;
SQInteger _scratchpadsize; SQInteger _scratchpadsize;
}; };
#define _sp(s) (_sharedstate->GetScratchPad(s)) #define _sp(s) (_sharedstate->GetScratchPad(s))
#define _spval (_sharedstate->GetScratchPad(-1)) #define _spval (_sharedstate->GetScratchPad(-1))
#define _table_ddel _table(_sharedstate->_table_default_delegate) #define _table_ddel _table(_sharedstate->_table_default_delegate)
#define _array_ddel _table(_sharedstate->_array_default_delegate) #define _array_ddel _table(_sharedstate->_array_default_delegate)
#define _string_ddel _table(_sharedstate->_string_default_delegate) #define _string_ddel _table(_sharedstate->_string_default_delegate)
#define _number_ddel _table(_sharedstate->_number_default_delegate) #define _number_ddel _table(_sharedstate->_number_default_delegate)
#define _generator_ddel _table(_sharedstate->_generator_default_delegate) #define _generator_ddel _table(_sharedstate->_generator_default_delegate)
#define _closure_ddel _table(_sharedstate->_closure_default_delegate) #define _closure_ddel _table(_sharedstate->_closure_default_delegate)
#define _thread_ddel _table(_sharedstate->_thread_default_delegate) #define _thread_ddel _table(_sharedstate->_thread_default_delegate)
#define _class_ddel _table(_sharedstate->_class_default_delegate) #define _class_ddel _table(_sharedstate->_class_default_delegate)
#define _instance_ddel _table(_sharedstate->_instance_default_delegate) #define _instance_ddel _table(_sharedstate->_instance_default_delegate)
#define _weakref_ddel _table(_sharedstate->_weakref_default_delegate) #define _weakref_ddel _table(_sharedstate->_weakref_default_delegate)

View File

@ -9,26 +9,26 @@
inline SQHash _hashstr (const SQChar *s, size_t l) inline SQHash _hashstr (const SQChar *s, size_t l)
{ {
SQHash h = (SQHash)l; /* seed */ SQHash h = (SQHash)l; /* seed */
size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */ size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */
for (; l>=step; l-=step) for (; l>=step; l-=step)
h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++)); h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++));
return h; return h;
} }
struct SQString : public SQRefCounted struct SQString : public SQRefCounted
{ {
SQString(){} SQString(){}
~SQString(){} ~SQString(){}
public: public:
static SQString *Create(SQSharedState *ss, const SQChar *, SQInteger len = -1 ); static SQString *Create(SQSharedState *ss, const SQChar *, SQInteger len = -1 );
SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
void Release(); void Release();
SQSharedState *_sharedstate; SQSharedState *_sharedstate;
SQString *_next; //chain for the string table SQString *_next; //chain for the string table
SQInteger _len; SQInteger _len;
SQHash _hash; SQHash _hash;
SQChar _val[1]; SQChar _val[1];
}; };

View File

@ -14,213 +14,213 @@
SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize) SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize)
{ {
SQInteger pow2size=MINPOWER2; SQInteger pow2size=MINPOWER2;
while(nInitialSize>pow2size)pow2size=pow2size<<1; while(nInitialSize>pow2size)pow2size=pow2size<<1;
AllocNodes(pow2size); AllocNodes(pow2size);
_usednodes = 0; _usednodes = 0;
_delegate = NULL; _delegate = NULL;
INIT_CHAIN(); INIT_CHAIN();
ADD_TO_CHAIN(&_sharedstate->_gc_chain,this); ADD_TO_CHAIN(&_sharedstate->_gc_chain,this);
} }
void SQTable::Remove(const SQObjectPtr &key) void SQTable::Remove(const SQObjectPtr &key)
{ {
_HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
if (n) { if (n) {
n->val.Null(); n->val.Null();
n->key.Null(); n->key.Null();
_usednodes--; _usednodes--;
Rehash(false); Rehash(false);
} }
} }
void SQTable::AllocNodes(SQInteger nSize) void SQTable::AllocNodes(SQInteger nSize)
{ {
_HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize); _HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize);
for(SQInteger i=0;i<nSize;i++){ for(SQInteger i=0;i<nSize;i++){
_HashNode &n = nodes[i]; _HashNode &n = nodes[i];
new (&n) _HashNode; new (&n) _HashNode;
n.next=NULL; n.next=NULL;
} }
_numofnodes=nSize; _numofnodes=nSize;
_nodes=nodes; _nodes=nodes;
_firstfree=&_nodes[_numofnodes-1]; _firstfree=&_nodes[_numofnodes-1];
} }
void SQTable::Rehash(bool force) void SQTable::Rehash(bool force)
{ {
SQInteger oldsize=_numofnodes; SQInteger oldsize=_numofnodes;
//prevent problems with the integer division //prevent problems with the integer division
if(oldsize<4)oldsize=4; if(oldsize<4)oldsize=4;
_HashNode *nold=_nodes; _HashNode *nold=_nodes;
SQInteger nelems=CountUsed(); SQInteger nelems=CountUsed();
if (nelems >= oldsize-oldsize/4) /* using more than 3/4? */ if (nelems >= oldsize-oldsize/4) /* using more than 3/4? */
AllocNodes(oldsize*2); AllocNodes(oldsize*2);
else if (nelems <= oldsize/4 && /* less than 1/4? */ else if (nelems <= oldsize/4 && /* less than 1/4? */
oldsize > MINPOWER2) oldsize > MINPOWER2)
AllocNodes(oldsize/2); AllocNodes(oldsize/2);
else if(force) else if(force)
AllocNodes(oldsize); AllocNodes(oldsize);
else else
return; return;
_usednodes = 0; _usednodes = 0;
for (SQInteger i=0; i<oldsize; i++) { for (SQInteger i=0; i<oldsize; i++) {
_HashNode *old = nold+i; _HashNode *old = nold+i;
if (sq_type(old->key) != OT_NULL) if (sq_type(old->key) != OT_NULL)
NewSlot(old->key,old->val); NewSlot(old->key,old->val);
} }
for(SQInteger k=0;k<oldsize;k++) for(SQInteger k=0;k<oldsize;k++)
nold[k].~_HashNode(); nold[k].~_HashNode();
SQ_FREE(nold,oldsize*sizeof(_HashNode)); SQ_FREE(nold,oldsize*sizeof(_HashNode));
} }
SQTable *SQTable::Clone() SQTable *SQTable::Clone()
{ {
SQTable *nt=Create(NULL,_numofnodes); SQTable *nt=Create(NULL,_numofnodes);
#ifdef _FAST_CLONE #ifdef _FAST_CLONE
_HashNode *basesrc = _nodes; _HashNode *basesrc = _nodes;
_HashNode *basedst = nt->_nodes; _HashNode *basedst = nt->_nodes;
_HashNode *src = _nodes; _HashNode *src = _nodes;
_HashNode *dst = nt->_nodes; _HashNode *dst = nt->_nodes;
SQInteger n = 0; SQInteger n = 0;
for(n = 0; n < _numofnodes; n++) { for(n = 0; n < _numofnodes; n++) {
dst->key = src->key; dst->key = src->key;
dst->val = src->val; dst->val = src->val;
if(src->next) { if(src->next) {
assert(src->next > basesrc); assert(src->next > basesrc);
dst->next = basedst + (src->next - basesrc); dst->next = basedst + (src->next - basesrc);
assert(dst != dst->next); assert(dst != dst->next);
} }
dst++; dst++;
src++; src++;
} }
assert(_firstfree > basesrc); assert(_firstfree > basesrc);
assert(_firstfree != NULL); assert(_firstfree != NULL);
nt->_firstfree = basedst + (_firstfree - basesrc); nt->_firstfree = basedst + (_firstfree - basesrc);
nt->_usednodes = _usednodes; nt->_usednodes = _usednodes;
#else #else
SQInteger ridx=0; SQInteger ridx=0;
SQObjectPtr key,val; SQObjectPtr key,val;
while((ridx=Next(true,ridx,key,val))!=-1){ while((ridx=Next(true,ridx,key,val))!=-1){
nt->NewSlot(key,val); nt->NewSlot(key,val);
} }
#endif #endif
nt->SetDelegate(_delegate); nt->SetDelegate(_delegate);
return nt; return nt;
} }
bool SQTable::Get(const SQObjectPtr &key,SQObjectPtr &val) bool SQTable::Get(const SQObjectPtr &key,SQObjectPtr &val)
{ {
if(sq_type(key) == OT_NULL) if(sq_type(key) == OT_NULL)
return false; return false;
_HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
if (n) { if (n) {
val = _realval(n->val); val = _realval(n->val);
return true; return true;
} }
return false; return false;
} }
bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val) bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
{ {
assert(sq_type(key) != OT_NULL); assert(sq_type(key) != OT_NULL);
SQHash h = HashObj(key) & (_numofnodes - 1); SQHash h = HashObj(key) & (_numofnodes - 1);
_HashNode *n = _Get(key, h); _HashNode *n = _Get(key, h);
if (n) { if (n) {
n->val = val; n->val = val;
return false; return false;
} }
_HashNode *mp = &_nodes[h]; _HashNode *mp = &_nodes[h];
n = mp; n = mp;
//key not found I'll insert it //key not found I'll insert it
//main pos is not free //main pos is not free
if(sq_type(mp->key) != OT_NULL) { if(sq_type(mp->key) != OT_NULL) {
n = _firstfree; /* get a free place */ n = _firstfree; /* get a free place */
SQHash mph = HashObj(mp->key) & (_numofnodes - 1); SQHash mph = HashObj(mp->key) & (_numofnodes - 1);
_HashNode *othern; /* main position of colliding node */ _HashNode *othern; /* main position of colliding node */
if (mp > n && (othern = &_nodes[mph]) != mp){ if (mp > n && (othern = &_nodes[mph]) != mp){
/* yes; move colliding node into free position */ /* yes; move colliding node into free position */
while (othern->next != mp){ while (othern->next != mp){
assert(othern->next != NULL); assert(othern->next != NULL);
othern = othern->next; /* find previous */ othern = othern->next; /* find previous */
} }
othern->next = n; /* redo the chain with `n' in place of `mp' */ othern->next = n; /* redo the chain with `n' in place of `mp' */
n->key = mp->key; n->key = mp->key;
n->val = mp->val;/* copy colliding node into free pos. (mp->next also goes) */ n->val = mp->val;/* copy colliding node into free pos. (mp->next also goes) */
n->next = mp->next; n->next = mp->next;
mp->key.Null(); mp->key.Null();
mp->val.Null(); mp->val.Null();
mp->next = NULL; /* now `mp' is free */ mp->next = NULL; /* now `mp' is free */
} }
else{ else{
/* new node will go into free position */ /* new node will go into free position */
n->next = mp->next; /* chain new position */ n->next = mp->next; /* chain new position */
mp->next = n; mp->next = n;
mp = n; mp = n;
} }
} }
mp->key = key; mp->key = key;
for (;;) { /* correct `firstfree' */ for (;;) { /* correct `firstfree' */
if (sq_type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) { if (sq_type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) {
mp->val = val; mp->val = val;
_usednodes++; _usednodes++;
return true; /* OK; table still has a free place */ return true; /* OK; table still has a free place */
} }
else if (_firstfree == _nodes) break; /* cannot decrement from here */ else if (_firstfree == _nodes) break; /* cannot decrement from here */
else (_firstfree)--; else (_firstfree)--;
} }
Rehash(true); Rehash(true);
return NewSlot(key, val); return NewSlot(key, val);
} }
SQInteger SQTable::Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) SQInteger SQTable::Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
{ {
SQInteger idx = (SQInteger)TranslateIndex(refpos); SQInteger idx = (SQInteger)TranslateIndex(refpos);
while (idx < _numofnodes) { while (idx < _numofnodes) {
if(sq_type(_nodes[idx].key) != OT_NULL) { if(sq_type(_nodes[idx].key) != OT_NULL) {
//first found //first found
_HashNode &n = _nodes[idx]; _HashNode &n = _nodes[idx];
outkey = n.key; outkey = n.key;
outval = getweakrefs?(SQObject)n.val:_realval(n.val); outval = getweakrefs?(SQObject)n.val:_realval(n.val);
//return idx for the next iteration //return idx for the next iteration
return ++idx; return ++idx;
} }
++idx; ++idx;
} }
//nothing to iterate anymore //nothing to iterate anymore
return -1; return -1;
} }
bool SQTable::Set(const SQObjectPtr &key, const SQObjectPtr &val) bool SQTable::Set(const SQObjectPtr &key, const SQObjectPtr &val)
{ {
_HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
if (n) { if (n) {
n->val = val; n->val = val;
return true; return true;
} }
return false; return false;
} }
void SQTable::_ClearNodes() void SQTable::_ClearNodes()
{ {
for(SQInteger i = 0;i < _numofnodes; i++) { _HashNode &n = _nodes[i]; n.key.Null(); n.val.Null(); } for(SQInteger i = 0;i < _numofnodes; i++) { _HashNode &n = _nodes[i]; n.key.Null(); n.val.Null(); }
} }
void SQTable::Finalize() void SQTable::Finalize()
{ {
_ClearNodes(); _ClearNodes();
SetDelegate(NULL); SetDelegate(NULL);
} }
void SQTable::Clear() void SQTable::Clear()
{ {
_ClearNodes(); _ClearNodes();
_usednodes = 0; _usednodes = 0;
Rehash(true); Rehash(true);
} }

View File

@ -20,92 +20,92 @@
inline SQHash HashObj(const SQObjectPtr &key) inline SQHash HashObj(const SQObjectPtr &key)
{ {
switch(sq_type(key)) { switch(sq_type(key)) {
case OT_STRING: return _string(key)->_hash; case OT_STRING: return _string(key)->_hash;
case OT_FLOAT: return (SQHash)((SQInteger)_float(key)); case OT_FLOAT: return (SQHash)((SQInteger)_float(key));
case OT_BOOL: case OT_INTEGER: return (SQHash)((SQInteger)_integer(key)); case OT_BOOL: case OT_INTEGER: return (SQHash)((SQInteger)_integer(key));
default: return hashptr(key._unVal.pRefCounted); default: return hashptr(key._unVal.pRefCounted);
} }
} }
struct SQTable : public SQDelegable struct SQTable : public SQDelegable
{ {
private: private:
struct _HashNode struct _HashNode
{ {
_HashNode() { next = NULL; } _HashNode() { next = NULL; }
SQObjectPtr val; SQObjectPtr val;
SQObjectPtr key; SQObjectPtr key;
_HashNode *next; _HashNode *next;
}; };
_HashNode *_firstfree; _HashNode *_firstfree;
_HashNode *_nodes; _HashNode *_nodes;
SQInteger _numofnodes; SQInteger _numofnodes;
SQInteger _usednodes; SQInteger _usednodes;
/////////////////////////// ///////////////////////////
void AllocNodes(SQInteger nSize); void AllocNodes(SQInteger nSize);
void Rehash(bool force); void Rehash(bool force);
SQTable(SQSharedState *ss, SQInteger nInitialSize); SQTable(SQSharedState *ss, SQInteger nInitialSize);
void _ClearNodes(); void _ClearNodes();
public: public:
static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize) static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize)
{ {
SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable)); SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));
new (newtable) SQTable(ss, nInitialSize); new (newtable) SQTable(ss, nInitialSize);
newtable->_delegate = NULL; newtable->_delegate = NULL;
return newtable; return newtable;
} }
void Finalize(); void Finalize();
SQTable *Clone(); SQTable *Clone();
~SQTable() ~SQTable()
{ {
SetDelegate(NULL); SetDelegate(NULL);
REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode(); for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();
SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode)); SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));
} }
inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash) inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash)
{ {
_HashNode *n = &_nodes[hash]; _HashNode *n = &_nodes[hash];
do{ do{
if(_rawval(n->key) == _rawval(key) && sq_type(n->key) == sq_type(key)){ if(_rawval(n->key) == _rawval(key) && sq_type(n->key) == sq_type(key)){
return n; return n;
} }
}while((n = n->next)); }while((n = n->next));
return NULL; return NULL;
} }
//for compiler use //for compiler use
inline bool GetStr(const SQChar* key,SQInteger keylen,SQObjectPtr &val) inline bool GetStr(const SQChar* key,SQInteger keylen,SQObjectPtr &val)
{ {
SQHash hash = _hashstr(key,keylen); SQHash hash = _hashstr(key,keylen);
_HashNode *n = &_nodes[hash & (_numofnodes - 1)]; _HashNode *n = &_nodes[hash & (_numofnodes - 1)];
_HashNode *res = NULL; _HashNode *res = NULL;
do{ do{
if(sq_type(n->key) == OT_STRING && (scstrcmp(_stringval(n->key),key) == 0)){ if(sq_type(n->key) == OT_STRING && (scstrcmp(_stringval(n->key),key) == 0)){
res = n; res = n;
break; break;
} }
}while((n = n->next)); }while((n = n->next));
if (res) { if (res) {
val = _realval(res->val); val = _realval(res->val);
return true; return true;
} }
return false; return false;
} }
bool Get(const SQObjectPtr &key,SQObjectPtr &val); bool Get(const SQObjectPtr &key,SQObjectPtr &val);
void Remove(const SQObjectPtr &key); void Remove(const SQObjectPtr &key);
bool Set(const SQObjectPtr &key, const SQObjectPtr &val); bool Set(const SQObjectPtr &key, const SQObjectPtr &val);
//returns true if a new slot has been created false if it was already present //returns true if a new slot has been created false if it was already present
bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val); bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);
SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
SQInteger CountUsed(){ return _usednodes;} SQInteger CountUsed(){ return _usednodes;}
void Clear(); void Clear();
void Release() void Release()
{ {
sq_delete(this, SQTable); sq_delete(this, SQTable);
} }
}; };

View File

@ -9,31 +9,31 @@
struct SQUserData : SQDelegable struct SQUserData : SQDelegable
{ {
SQUserData(SQSharedState *ss){ _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); } SQUserData(SQSharedState *ss){ _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); }
~SQUserData() ~SQUserData()
{ {
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this); REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this);
SetDelegate(NULL); SetDelegate(NULL);
} }
static SQUserData* Create(SQSharedState *ss, SQInteger size) static SQUserData* Create(SQSharedState *ss, SQInteger size)
{ {
SQUserData* ud = (SQUserData*)SQ_MALLOC(sq_aligning(sizeof(SQUserData))+size); SQUserData* ud = (SQUserData*)SQ_MALLOC(sq_aligning(sizeof(SQUserData))+size);
new (ud) SQUserData(ss); new (ud) SQUserData(ss);
ud->_size = size; ud->_size = size;
ud->_typetag = 0; ud->_typetag = 0;
return ud; return ud;
} }
void Release() { void Release() {
if (_hook) _hook((SQUserPointer)sq_aligning(this + 1),_size); if (_hook) _hook((SQUserPointer)sq_aligning(this + 1),_size);
SQInteger tsize = _size; SQInteger tsize = _size;
this->~SQUserData(); this->~SQUserData();
SQ_FREE(this, sq_aligning(sizeof(SQUserData)) + tsize); SQ_FREE(this, sq_aligning(sizeof(SQUserData)) + tsize);
} }
SQInteger _size; SQInteger _size;
SQRELEASEHOOK _hook; SQRELEASEHOOK _hook;
SQUserPointer _typetag; SQUserPointer _typetag;
//SQChar _val[1]; //SQChar _val[1];
}; };

View File

@ -23,98 +23,98 @@ void sq_vm_free(void *p,SQUnsignedInteger size);
template<typename T> class sqvector template<typename T> class sqvector
{ {
public: public:
sqvector() sqvector()
{ {
_vals = NULL; _vals = NULL;
_size = 0; _size = 0;
_allocated = 0; _allocated = 0;
} }
sqvector(const sqvector<T>& v) sqvector(const sqvector<T>& v)
{ {
copy(v); copy(v);
} }
void copy(const sqvector<T>& v) void copy(const sqvector<T>& v)
{ {
if(_size) { if(_size) {
resize(0); //destroys all previous stuff resize(0); //destroys all previous stuff
} }
//resize(v._size); //resize(v._size);
if(v._size > _allocated) { if(v._size > _allocated) {
_realloc(v._size); _realloc(v._size);
} }
for(SQUnsignedInteger i = 0; i < v._size; i++) { for(SQUnsignedInteger i = 0; i < v._size; i++) {
new ((void *)&_vals[i]) T(v._vals[i]); new ((void *)&_vals[i]) T(v._vals[i]);
} }
_size = v._size; _size = v._size;
} }
~sqvector() ~sqvector()
{ {
if(_allocated) { if(_allocated) {
for(SQUnsignedInteger i = 0; i < _size; i++) for(SQUnsignedInteger i = 0; i < _size; i++)
_vals[i].~T(); _vals[i].~T();
SQ_FREE(_vals, (_allocated * sizeof(T))); SQ_FREE(_vals, (_allocated * sizeof(T)));
} }
} }
void reserve(SQUnsignedInteger newsize) { _realloc(newsize); } void reserve(SQUnsignedInteger newsize) { _realloc(newsize); }
void resize(SQUnsignedInteger newsize, const T& fill = T()) void resize(SQUnsignedInteger newsize, const T& fill = T())
{ {
if(newsize > _allocated) if(newsize > _allocated)
_realloc(newsize); _realloc(newsize);
if(newsize > _size) { if(newsize > _size) {
while(_size < newsize) { while(_size < newsize) {
new ((void *)&_vals[_size]) T(fill); new ((void *)&_vals[_size]) T(fill);
_size++; _size++;
} }
} }
else{ else{
for(SQUnsignedInteger i = newsize; i < _size; i++) { for(SQUnsignedInteger i = newsize; i < _size; i++) {
_vals[i].~T(); _vals[i].~T();
} }
_size = newsize; _size = newsize;
} }
} }
void shrinktofit() { if(_size > 4) { _realloc(_size); } } void shrinktofit() { if(_size > 4) { _realloc(_size); } }
T& top() const { return _vals[_size - 1]; } T& top() const { return _vals[_size - 1]; }
inline SQUnsignedInteger size() const { return _size; } inline SQUnsignedInteger size() const { return _size; }
bool empty() const { return (_size <= 0); } bool empty() const { return (_size <= 0); }
inline T &push_back(const T& val = T()) inline T &push_back(const T& val = T())
{ {
if(_allocated <= _size) if(_allocated <= _size)
_realloc(_size * 2); _realloc(_size * 2);
return *(new ((void *)&_vals[_size++]) T(val)); return *(new ((void *)&_vals[_size++]) T(val));
} }
inline void pop_back() inline void pop_back()
{ {
_size--; _vals[_size].~T(); _size--; _vals[_size].~T();
} }
void insert(SQUnsignedInteger idx, const T& val) void insert(SQUnsignedInteger idx, const T& val)
{ {
resize(_size + 1); resize(_size + 1);
for(SQUnsignedInteger i = _size - 1; i > idx; i--) { for(SQUnsignedInteger i = _size - 1; i > idx; i--) {
_vals[i] = _vals[i - 1]; _vals[i] = _vals[i - 1];
} }
_vals[idx] = val; _vals[idx] = val;
} }
void remove(SQUnsignedInteger idx) void remove(SQUnsignedInteger idx)
{ {
_vals[idx].~T(); _vals[idx].~T();
if(idx < (_size - 1)) { if(idx < (_size - 1)) {
memmove(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1)); memmove(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1));
} }
_size--; _size--;
} }
SQUnsignedInteger capacity() { return _allocated; } SQUnsignedInteger capacity() { return _allocated; }
inline T &back() const { return _vals[_size - 1]; } inline T &back() const { return _vals[_size - 1]; }
inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; } inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; }
T* _vals; T* _vals;
private: private:
void _realloc(SQUnsignedInteger newsize) void _realloc(SQUnsignedInteger newsize)
{ {
newsize = (newsize > 0)?newsize:4; newsize = (newsize > 0)?newsize:4;
_vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T)); _vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T));
_allocated = newsize; _allocated = newsize;
} }
SQUnsignedInteger _size; SQUnsignedInteger _size;
SQUnsignedInteger _allocated; SQUnsignedInteger _allocated;
}; };

File diff suppressed because it is too large Load Diff

View File

@ -18,19 +18,19 @@
#define DONT_FALL_BACK 666 #define DONT_FALL_BACK 666
//#define EXISTS_FALL_BACK -1 //#define EXISTS_FALL_BACK -1
#define GET_FLAG_RAW 0x00000001 #define GET_FLAG_RAW 0x00000001
#define GET_FLAG_DO_NOT_RAISE_ERROR 0x00000002 #define GET_FLAG_DO_NOT_RAISE_ERROR 0x00000002
//base lib //base lib
void sq_base_register(HRABBITVM v); void sq_base_register(HRABBITVM v);
struct SQExceptionTrap{ struct SQExceptionTrap{
SQExceptionTrap() {} SQExceptionTrap() {}
SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;} SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}
SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et; } SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et; }
SQInteger _stackbase; SQInteger _stackbase;
SQInteger _stacksize; SQInteger _stacksize;
SQInstruction *_ip; SQInstruction *_ip;
SQInteger _extarget; SQInteger _extarget;
}; };
#define _INLINE #define _INLINE
@ -39,152 +39,152 @@ typedef sqvector<SQExceptionTrap> ExceptionsTraps;
struct SQVM : public CHAINABLE_OBJ struct SQVM : public CHAINABLE_OBJ
{ {
struct CallInfo{ struct CallInfo{
//CallInfo() { _generator = NULL;} //CallInfo() { _generator = NULL;}
SQInstruction *_ip; SQInstruction *_ip;
SQObjectPtr *_literals; SQObjectPtr *_literals;
SQObjectPtr _closure; SQObjectPtr _closure;
SQGenerator *_generator; SQGenerator *_generator;
SQInt32 _etraps; SQInt32 _etraps;
SQInt32 _prevstkbase; SQInt32 _prevstkbase;
SQInt32 _prevtop; SQInt32 _prevtop;
SQInt32 _target; SQInt32 _target;
SQInt32 _ncalls; SQInt32 _ncalls;
SQBool _root; SQBool _root;
}; };
typedef sqvector<CallInfo> CallInfoVec; typedef sqvector<CallInfo> CallInfoVec;
public: public:
void DebugHookProxy(SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname); void DebugHookProxy(SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname);
static void _DebugHookProxy(HRABBITVM v, SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname); static void _DebugHookProxy(HRABBITVM v, SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname);
enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM,ET_RESUME_THROW_VM }; enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM,ET_RESUME_THROW_VM };
SQVM(SQSharedState *ss); SQVM(SQSharedState *ss);
~SQVM(); ~SQVM();
bool Init(SQVM *friendvm, SQInteger stacksize); bool Init(SQVM *friendvm, SQInteger stacksize);
bool Execute(SQObjectPtr &func, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL); bool Execute(SQObjectPtr &func, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL);
//starts a native call return when the NATIVE closure returns //starts a native call return when the NATIVE closure returns
bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger newbase, SQObjectPtr &retval, SQInt32 target, bool &suspend,bool &tailcall); bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger newbase, SQObjectPtr &retval, SQInt32 target, bool &suspend,bool &tailcall);
bool TailCall(SQClosure *closure, SQInteger firstparam, SQInteger nparams); bool TailCall(SQClosure *closure, SQInteger firstparam, SQInteger nparams);
//starts a RABBIT call in the same "Execution loop" //starts a RABBIT call in the same "Execution loop"
bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall); bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall);
bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor); bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor);
//call a generic closure pure RABBIT or NATIVE //call a generic closure pure RABBIT or NATIVE
bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror); bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror);
SQRESULT Suspend(); SQRESULT Suspend();
void CallDebugHook(SQInteger type,SQInteger forcedline=0); void CallDebugHook(SQInteger type,SQInteger forcedline=0);
void CallErrorHandler(SQObjectPtr &e); void CallErrorHandler(SQObjectPtr &e);
bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, SQUnsignedInteger getflags, SQInteger selfidx); bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, SQUnsignedInteger getflags, SQInteger selfidx);
SQInteger FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest); SQInteger FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest);
bool InvokeDefaultDelegate(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest); bool InvokeDefaultDelegate(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest);
bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, SQInteger selfidx); bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, SQInteger selfidx);
SQInteger FallBackSet(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val); SQInteger FallBackSet(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val);
bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic); bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic);
bool NewSlotA(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,const SQObjectPtr &attrs,bool bstatic,bool raw); bool NewSlotA(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,const SQObjectPtr &attrs,bool bstatic,bool raw);
bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res); bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res);
bool Clone(const SQObjectPtr &self, SQObjectPtr &target); bool Clone(const SQObjectPtr &self, SQObjectPtr &target);
bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res); bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res);
bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest); bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);
static bool IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res); static bool IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res);
bool ToString(const SQObjectPtr &o,SQObjectPtr &res); bool ToString(const SQObjectPtr &o,SQObjectPtr &res);
SQString *PrintObjVal(const SQObjectPtr &o); SQString *PrintObjVal(const SQObjectPtr &o);
void Raise_Error(const SQChar *s, ...); void Raise_Error(const SQChar *s, ...);
void Raise_Error(const SQObjectPtr &desc); void Raise_Error(const SQObjectPtr &desc);
void Raise_IdxError(const SQObjectPtr &o); void Raise_IdxError(const SQObjectPtr &o);
void Raise_CompareError(const SQObject &o1, const SQObject &o2); void Raise_CompareError(const SQObject &o1, const SQObject &o2);
void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type); void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type);
void FindOuter(SQObjectPtr &target, SQObjectPtr *stackindex); void FindOuter(SQObjectPtr &target, SQObjectPtr *stackindex);
void RelocateOuters(); void RelocateOuters();
void CloseOuters(SQObjectPtr *stackindex); void CloseOuters(SQObjectPtr *stackindex);
bool TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest); bool TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);
bool CallMetaMethod(SQObjectPtr &closure, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres); bool CallMetaMethod(SQObjectPtr &closure, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres);
bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest); bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);
bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval); bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval);
//new stuff //new stuff
_INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2); bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
_INLINE bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2); bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
_INLINE bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1); bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);
_INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res); bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res);
bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func); bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func);
bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs); bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs);
//return true if the loop is finished //return true if the loop is finished
bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump); bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump);
//_INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr); //bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
_INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr); bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
_INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix,SQInteger arg0); bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix,SQInteger arg0);
#ifdef _DEBUG_DUMP #ifdef _DEBUG_DUMP
void dumpstack(SQInteger stackbase=-1, bool dumpall = false); void dumpstack(SQInteger stackbase=-1, bool dumpall = false);
#endif #endif
void Finalize(); void Finalize();
void GrowCallStack() { void GrowCallStack() {
SQInteger newsize = _alloccallsstacksize*2; SQInteger newsize = _alloccallsstacksize*2;
_callstackdata.resize(newsize); _callstackdata.resize(newsize);
_callsstack = &_callstackdata[0]; _callsstack = &_callstackdata[0];
_alloccallsstacksize = newsize; _alloccallsstacksize = newsize;
} }
bool EnterFrame(SQInteger newbase, SQInteger newtop, bool tailcall); bool EnterFrame(SQInteger newbase, SQInteger newtop, bool tailcall);
void LeaveFrame(); void LeaveFrame();
void Release(){ sq_delete(this,SQVM); } void Release(){ sq_delete(this,SQVM); }
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
//stack functions for the api //stack functions for the api
void Remove(SQInteger n); void Remove(SQInteger n);
static bool IsFalse(SQObjectPtr &o); static bool IsFalse(SQObjectPtr &o);
void Pop(); void Pop();
void Pop(SQInteger n); void Pop(SQInteger n);
void Push(const SQObjectPtr &o); void Push(const SQObjectPtr &o);
void PushNull(); void PushNull();
SQObjectPtr &Top(); SQObjectPtr &Top();
SQObjectPtr &PopGet(); SQObjectPtr &PopGet();
SQObjectPtr &GetUp(SQInteger n); SQObjectPtr &GetUp(SQInteger n);
SQObjectPtr &GetAt(SQInteger n); SQObjectPtr &GetAt(SQInteger n);
SQObjectPtrVec _stack; SQObjectPtrVec _stack;
SQInteger _top; SQInteger _top;
SQInteger _stackbase; SQInteger _stackbase;
SQOuter *_openouters; SQOuter *_openouters;
SQObjectPtr _roottable; SQObjectPtr _roottable;
SQObjectPtr _lasterror; SQObjectPtr _lasterror;
SQObjectPtr _errorhandler; SQObjectPtr _errorhandler;
bool _debughook; bool _debughook;
SQDEBUGHOOK _debughook_native; SQDEBUGHOOK _debughook_native;
SQObjectPtr _debughook_closure; SQObjectPtr _debughook_closure;
SQObjectPtr temp_reg; SQObjectPtr temp_reg;
CallInfo* _callsstack; CallInfo* _callsstack;
SQInteger _callsstacksize; SQInteger _callsstacksize;
SQInteger _alloccallsstacksize; SQInteger _alloccallsstacksize;
sqvector<CallInfo> _callstackdata; sqvector<CallInfo> _callstackdata;
ExceptionsTraps _etraps; ExceptionsTraps _etraps;
CallInfo *ci; CallInfo *ci;
SQUserPointer _foreignptr; SQUserPointer _foreignptr;
//VMs sharing the same state //VMs sharing the same state
SQSharedState *_sharedstate; SQSharedState *_sharedstate;
SQInteger _nnativecalls; SQInteger _nnativecalls;
SQInteger _nmetamethodscall; SQInteger _nmetamethodscall;
SQRELEASEHOOK _releasehook; SQRELEASEHOOK _releasehook;
//suspend infos //suspend infos
SQBool _suspended; SQBool _suspended;
SQBool _suspended_root; SQBool _suspended_root;
SQInteger _suspended_target; SQInteger _suspended_target;
SQInteger _suspended_traps; SQInteger _suspended_traps;
}; };
struct AutoDec{ struct AutoDec{
AutoDec(SQInteger *n) { _n = n; } AutoDec(SQInteger *n) { _n = n; }
~AutoDec() { (*_n)--; } ~AutoDec() { (*_n)--; }
SQInteger *_n; SQInteger *_n;
}; };
inline SQObjectPtr &stack_get(HRABBITVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));} inline SQObjectPtr &stack_get(HRABBITVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}
@ -192,17 +192,17 @@ inline SQObjectPtr &stack_get(HRABBITVM v,SQInteger idx){return ((idx>=0)?(v->Ge
#define _ss(_vm_) (_vm_)->_sharedstate #define _ss(_vm_) (_vm_)->_sharedstate
#define PUSH_CALLINFO(v,nci){ \ #define PUSH_CALLINFO(v,nci){ \
SQInteger css = v->_callsstacksize; \ SQInteger css = v->_callsstacksize; \
if(css == v->_alloccallsstacksize) { \ if(css == v->_alloccallsstacksize) { \
v->GrowCallStack(); \ v->GrowCallStack(); \
} \ } \
v->ci = &v->_callsstack[css]; \ v->ci = &v->_callsstack[css]; \
*(v->ci) = nci; \ *(v->ci) = nci; \
v->_callsstacksize++; \ v->_callsstacksize++; \
} }
#define POP_CALLINFO(v){ \ #define POP_CALLINFO(v){ \
SQInteger css = --v->_callsstacksize; \ SQInteger css = --v->_callsstacksize; \
v->ci->_closure.Null(); \ v->ci->_closure.Null(); \
v->ci = css?&v->_callsstack[css-1]:NULL; \ v->ci = css?&v->_callsstack[css-1]:NULL; \
} }