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

View File

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

View File

@ -20,59 +20,59 @@
void printfunc(HSQUIRRELVM v,const SQChar *s,...)
{
va_list vl;
va_start(vl, s);
scvprintf(stdout, s, vl);
va_end(vl);
va_list vl;
va_start(vl, s);
scvprintf(stdout, s, vl);
va_end(vl);
}
void errorfunc(HSQUIRRELVM v,const SQChar *s,...)
{
va_list vl;
va_start(vl, s);
scvprintf(stderr, s, vl);
va_end(vl);
va_list vl;
va_start(vl, s);
scvprintf(stderr, s, vl);
va_end(vl);
}
void call_foo(HSQUIRRELVM v, int n,float f,const SQChar *s)
{
SQInteger top = sq_gettop(v); //saves the stack size before the call
sq_pushroottable(v); //pushes the global table
sq_pushstring(v,_SC("foo"),-1);
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_pushinteger(v,n);
sq_pushfloat(v,f);
sq_pushstring(v,s,-1);
sq_call(v,4,SQFalse,SQTrue); //calls the function
}
sq_settop(v,top); //restores the original stack size
SQInteger top = sq_gettop(v); //saves the stack size before the call
sq_pushroottable(v); //pushes the global table
sq_pushstring(v,_SC("foo"),-1);
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_pushinteger(v,n);
sq_pushfloat(v,f);
sq_pushstring(v,s,-1);
sq_call(v,4,SQFalse,SQTrue); //calls the function
}
sq_settop(v,top); //restores the original stack size
}
int main(int argc, char* argv[])
{
HSQUIRRELVM v;
v = sq_open(1024); // creates a VM with initial stack size 1024
HSQUIRRELVM v;
v = sq_open(1024); // creates a VM with initial stack size 1024
//REGISTRATION OF STDLIB
//sq_pushroottable(v); //push the root table where the std function will be registered
//sqstd_register_iolib(v); //registers a library
// ... call here other stdlibs string,math etc...
//sq_pop(v,1); //pops the root table
//END REGISTRATION OF STDLIB
//REGISTRATION OF STDLIB
//sq_pushroottable(v); //push the root table where the std function will be registered
//sqstd_register_iolib(v); //registers a library
// ... call here other stdlibs string,math etc...
//sq_pop(v,1); //pops the root table
//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)
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"));
}
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
{
call_foo(v,1,2.5,_SC("teststring"));
}
sq_pop(v,1); //pops the root table
sq_close(v);
sq_pop(v,1); //pops the root table
sq_close(v);
return 0;
return 0;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -10,87 +10,87 @@
struct SQArray : public CHAINABLE_OBJ
{
private:
SQArray(SQSharedState *ss,SQInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
~SQArray()
{
REMOVE_FROM_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()
{
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
}
public:
static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){
SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray));
new (newarray) SQArray(ss,nInitialSize);
return newarray;
}
void Finalize(){
_values.resize(0);
}
bool Get(const SQInteger nidx,SQObjectPtr &val)
{
if(nidx>=0 && nidx<(SQInteger)_values.size()){
SQObjectPtr &o = _values[nidx];
val = _realval(o);
return true;
}
else return false;
}
bool Set(const SQInteger nidx,const SQObjectPtr &val)
{
if(nidx>=0 && nidx<(SQInteger)_values.size()){
_values[nidx]=val;
return true;
}
else return false;
}
SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval)
{
SQUnsignedInteger idx=TranslateIndex(refpos);
while(idx<_values.size()){
//first found
outkey=(SQInteger)idx;
SQObjectPtr &o = _values[idx];
outval = _realval(o);
//return idx for the next iteration
return ++idx;
}
//nothing to iterate anymore
return -1;
}
SQArray *Clone(){SQArray *anew=Create(NULL,0); anew->_values.copy(_values); return anew; }
SQInteger Size() const {return _values.size();}
void Resize(SQInteger size)
{
SQObjectPtr _null;
Resize(size,_null);
}
void Resize(SQInteger size,SQObjectPtr &fill) { _values.resize(size,fill); ShrinkIfNeeded(); }
void Reserve(SQInteger size) { _values.reserve(size); }
void Append(const SQObject &o){_values.push_back(o);}
void Extend(const SQArray *a);
SQObjectPtr &Top(){return _values.top();}
void Pop(){_values.pop_back(); ShrinkIfNeeded(); }
bool Insert(SQInteger idx,const SQObject &val){
if(idx < 0 || idx > (SQInteger)_values.size())
return false;
_values.insert(idx,val);
return true;
}
void ShrinkIfNeeded() {
if(_values.size() <= _values.capacity()>>2) //shrink the array
_values.shrinktofit();
}
bool Remove(SQInteger idx){
if(idx < 0 || idx >= (SQInteger)_values.size())
return false;
_values.remove(idx);
ShrinkIfNeeded();
return true;
}
void Release()
{
sq_delete(this,SQArray);
}
static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){
SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray));
new (newarray) SQArray(ss,nInitialSize);
return newarray;
}
void Finalize(){
_values.resize(0);
}
bool Get(const SQInteger nidx,SQObjectPtr &val)
{
if(nidx>=0 && nidx<(SQInteger)_values.size()){
SQObjectPtr &o = _values[nidx];
val = _realval(o);
return true;
}
else return false;
}
bool Set(const SQInteger nidx,const SQObjectPtr &val)
{
if(nidx>=0 && nidx<(SQInteger)_values.size()){
_values[nidx]=val;
return true;
}
else return false;
}
SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval)
{
SQUnsignedInteger idx=TranslateIndex(refpos);
while(idx<_values.size()){
//first found
outkey=(SQInteger)idx;
SQObjectPtr &o = _values[idx];
outval = _realval(o);
//return idx for the next iteration
return ++idx;
}
//nothing to iterate anymore
return -1;
}
SQArray *Clone(){SQArray *anew=Create(NULL,0); anew->_values.copy(_values); return anew; }
SQInteger Size() const {return _values.size();}
void Resize(SQInteger size)
{
SQObjectPtr _null;
Resize(size,_null);
}
void Resize(SQInteger size,SQObjectPtr &fill) { _values.resize(size,fill); ShrinkIfNeeded(); }
void Reserve(SQInteger size) { _values.reserve(size); }
void Append(const SQObject &o){_values.push_back(o);}
void Extend(const SQArray *a);
SQObjectPtr &Top(){return _values.top();}
void Pop(){_values.pop_back(); ShrinkIfNeeded(); }
bool Insert(SQInteger idx,const SQObject &val){
if(idx < 0 || idx > (SQInteger)_values.size())
return false;
_values.insert(idx,val);
return true;
}
void ShrinkIfNeeded() {
if(_values.size() <= _values.capacity()>>2) //shrink the array
_values.shrinktofit();
}
bool Remove(SQInteger idx){
if(idx < 0 || idx >= (SQInteger)_values.size())
return false;
_values.remove(idx);
ShrinkIfNeeded();
return true;
}
void Release()
{
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)
{
_base = base;
_typetag = 0;
_hook = NULL;
_udsize = 0;
_locked = false;
_constructoridx = -1;
if(_base) {
_constructoridx = _base->_constructoridx;
_udsize = _base->_udsize;
_defaultvalues.copy(base->_defaultvalues);
_methods.copy(base->_methods);
_COPY_VECTOR(_metamethods,base->_metamethods,MT_LAST);
__ObjAddRef(_base);
}
_members = base?base->_members->Clone() : SQTable::Create(ss,0);
__ObjAddRef(_members);
_base = base;
_typetag = 0;
_hook = NULL;
_udsize = 0;
_locked = false;
_constructoridx = -1;
if(_base) {
_constructoridx = _base->_constructoridx;
_udsize = _base->_udsize;
_defaultvalues.copy(base->_defaultvalues);
_methods.copy(base->_methods);
_COPY_VECTOR(_metamethods,base->_metamethods,MT_LAST);
__ObjAddRef(_base);
}
_members = base?base->_members->Clone() : SQTable::Create(ss,0);
__ObjAddRef(_members);
INIT_CHAIN();
ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
INIT_CHAIN();
ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
}
void SQClass::Finalize() {
_attributes.Null();
_NULL_SQOBJECT_VECTOR(_defaultvalues,_defaultvalues.size());
_methods.resize(0);
_NULL_SQOBJECT_VECTOR(_metamethods,MT_LAST);
__ObjRelease(_members);
if(_base) {
__ObjRelease(_base);
}
_attributes.Null();
_NULL_SQOBJECT_VECTOR(_defaultvalues,_defaultvalues.size());
_methods.resize(0);
_NULL_SQOBJECT_VECTOR(_metamethods,MT_LAST);
__ObjRelease(_members);
if(_base) {
__ObjRelease(_base);
}
}
SQClass::~SQClass()
{
REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
Finalize();
REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
Finalize();
}
bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic)
{
SQObjectPtr temp;
bool belongs_to_static_table = sq_type(val) == OT_CLOSURE || sq_type(val) == OT_NATIVECLOSURE || bstatic;
if(_locked && !belongs_to_static_table)
return false; //the class already has an instance so cannot be modified
if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value
{
_defaultvalues[_member_idx(temp)].val = val;
return true;
}
if(belongs_to_static_table) {
SQInteger mmidx;
if((sq_type(val) == OT_CLOSURE || sq_type(val) == OT_NATIVECLOSURE) &&
(mmidx = ss->GetMetaMethodIdxByName(key)) != -1) {
_metamethods[mmidx] = val;
}
else {
SQObjectPtr theval = val;
if(_base && sq_type(val) == OT_CLOSURE) {
theval = _closure(val)->Clone();
_closure(theval)->_base = _base;
__ObjAddRef(_base); //ref for the closure
}
if(sq_type(temp) == OT_NULL) {
bool isconstructor;
SQVM::IsEqual(ss->_constructoridx, key, isconstructor);
if(isconstructor) {
_constructoridx = (SQInteger)_methods.size();
}
SQClassMember m;
m.val = theval;
_members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size())));
_methods.push_back(m);
}
else {
_methods[_member_idx(temp)].val = theval;
}
}
return true;
}
SQClassMember m;
m.val = val;
_members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size())));
_defaultvalues.push_back(m);
return true;
SQObjectPtr temp;
bool belongs_to_static_table = sq_type(val) == OT_CLOSURE || sq_type(val) == OT_NATIVECLOSURE || bstatic;
if(_locked && !belongs_to_static_table)
return false; //the class already has an instance so cannot be modified
if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value
{
_defaultvalues[_member_idx(temp)].val = val;
return true;
}
if(belongs_to_static_table) {
SQInteger mmidx;
if((sq_type(val) == OT_CLOSURE || sq_type(val) == OT_NATIVECLOSURE) &&
(mmidx = ss->GetMetaMethodIdxByName(key)) != -1) {
_metamethods[mmidx] = val;
}
else {
SQObjectPtr theval = val;
if(_base && sq_type(val) == OT_CLOSURE) {
theval = _closure(val)->Clone();
_closure(theval)->_base = _base;
__ObjAddRef(_base); //ref for the closure
}
if(sq_type(temp) == OT_NULL) {
bool isconstructor;
SQVM::IsEqual(ss->_constructoridx, key, isconstructor);
if(isconstructor) {
_constructoridx = (SQInteger)_methods.size();
}
SQClassMember m;
m.val = theval;
_members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size())));
_methods.push_back(m);
}
else {
_methods[_member_idx(temp)].val = theval;
}
}
return true;
}
SQClassMember m;
m.val = val;
_members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size())));
_defaultvalues.push_back(m);
return true;
}
SQInstance *SQClass::CreateInstance()
{
if(!_locked) Lock();
return SQInstance::Create(NULL,this);
if(!_locked) Lock();
return SQInstance::Create(NULL,this);
}
SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
{
SQObjectPtr oval;
SQInteger idx = _members->Next(false,refpos,outkey,oval);
if(idx != -1) {
if(_ismethod(oval)) {
outval = _methods[_member_idx(oval)].val;
}
else {
SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val;
outval = _realval(o);
}
}
return idx;
SQObjectPtr oval;
SQInteger idx = _members->Next(false,refpos,outkey,oval);
if(idx != -1) {
if(_ismethod(oval)) {
outval = _methods[_member_idx(oval)].val;
}
else {
SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val;
outval = _realval(o);
}
}
return idx;
}
bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val)
{
SQObjectPtr idx;
if(_members->Get(key,idx)) {
if(_isfield(idx))
_defaultvalues[_member_idx(idx)].attrs = val;
else
_methods[_member_idx(idx)].attrs = val;
return true;
}
return false;
SQObjectPtr idx;
if(_members->Get(key,idx)) {
if(_isfield(idx))
_defaultvalues[_member_idx(idx)].attrs = val;
else
_methods[_member_idx(idx)].attrs = val;
return true;
}
return false;
}
bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval)
{
SQObjectPtr idx;
if(_members->Get(key,idx)) {
outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs);
return true;
}
return false;
SQObjectPtr idx;
if(_members->Get(key,idx)) {
outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs);
return true;
}
return false;
}
///////////////////////////////////////////////////////////////////////
void SQInstance::Init(SQSharedState *ss)
{
_userpointer = NULL;
_hook = NULL;
__ObjAddRef(_class);
_delegate = _class->_members;
INIT_CHAIN();
ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
_userpointer = NULL;
_hook = NULL;
__ObjAddRef(_class);
_delegate = _class->_members;
INIT_CHAIN();
ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
}
SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize)
{
_memsize = memsize;
_class = c;
SQUnsignedInteger nvalues = _class->_defaultvalues.size();
for(SQUnsignedInteger n = 0; n < nvalues; n++) {
new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val);
}
Init(ss);
_memsize = memsize;
_class = c;
SQUnsignedInteger nvalues = _class->_defaultvalues.size();
for(SQUnsignedInteger n = 0; n < nvalues; n++) {
new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val);
}
Init(ss);
}
SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize)
{
_memsize = memsize;
_class = i->_class;
SQUnsignedInteger nvalues = _class->_defaultvalues.size();
for(SQUnsignedInteger n = 0; n < nvalues; n++) {
new (&_values[n]) SQObjectPtr(i->_values[n]);
}
Init(ss);
_memsize = memsize;
_class = i->_class;
SQUnsignedInteger nvalues = _class->_defaultvalues.size();
for(SQUnsignedInteger n = 0; n < nvalues; n++) {
new (&_values[n]) SQObjectPtr(i->_values[n]);
}
Init(ss);
}
void SQInstance::Finalize()
{
SQUnsignedInteger nvalues = _class->_defaultvalues.size();
__ObjRelease(_class);
_NULL_SQOBJECT_VECTOR(_values,nvalues);
SQUnsignedInteger nvalues = _class->_defaultvalues.size();
__ObjRelease(_class);
_NULL_SQOBJECT_VECTOR(_values,nvalues);
}
SQInstance::~SQInstance()
{
REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
if(_class){ Finalize(); } //if _class is null it was already finalized by the GC
REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
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)
{
if(sq_type(_class->_metamethods[mm]) != OT_NULL) {
res = _class->_metamethods[mm];
return true;
}
return false;
if(sq_type(_class->_metamethods[mm]) != OT_NULL) {
res = _class->_metamethods[mm];
return true;
}
return false;
}
bool SQInstance::InstanceOf(SQClass *trg)
{
SQClass *parent = _class;
while(parent != NULL) {
if(parent == trg)
return true;
parent = parent->_base;
}
return false;
SQClass *parent = _class;
while(parent != NULL) {
if(parent == trg)
return true;
parent = parent->_base;
}
return false;
}

View File

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

View File

@ -14,55 +14,55 @@ struct SQClass;
struct SQClosure : public CHAINABLE_OBJ
{
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:
static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func,SQWeakRef *root){
SQInteger size = _CALC_CLOSURE_SIZE(func);
SQClosure *nc=(SQClosure*)SQ_MALLOC(size);
new (nc) SQClosure(ss,func);
nc->_outervalues = (SQObjectPtr *)(nc + 1);
nc->_defaultparams = &nc->_outervalues[func->_noutervalues];
nc->_root = root;
__ObjAddRef(nc->_root);
_CONSTRUCT_VECTOR(SQObjectPtr,func->_noutervalues,nc->_outervalues);
_CONSTRUCT_VECTOR(SQObjectPtr,func->_ndefaultparams,nc->_defaultparams);
return nc;
}
void Release(){
SQFunctionProto *f = _function;
SQInteger size = _CALC_CLOSURE_SIZE(f);
_DESTRUCT_VECTOR(SQObjectPtr,f->_noutervalues,_outervalues);
_DESTRUCT_VECTOR(SQObjectPtr,f->_ndefaultparams,_defaultparams);
__ObjRelease(_function);
this->~SQClosure();
sq_vm_free(this,size);
}
void SetRoot(SQWeakRef *r)
{
__ObjRelease(_root);
_root = r;
__ObjAddRef(_root);
}
SQClosure *Clone()
{
SQFunctionProto *f = _function;
SQClosure * ret = SQClosure::Create(NULL,f,_root);
ret->_env = _env;
if(ret->_env) __ObjAddRef(ret->_env);
_COPY_VECTOR(ret->_outervalues,_outervalues,f->_noutervalues);
_COPY_VECTOR(ret->_defaultparams,_defaultparams,f->_ndefaultparams);
return ret;
}
~SQClosure();
static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func,SQWeakRef *root){
SQInteger size = _CALC_CLOSURE_SIZE(func);
SQClosure *nc=(SQClosure*)SQ_MALLOC(size);
new (nc) SQClosure(ss,func);
nc->_outervalues = (SQObjectPtr *)(nc + 1);
nc->_defaultparams = &nc->_outervalues[func->_noutervalues];
nc->_root = root;
__ObjAddRef(nc->_root);
_CONSTRUCT_VECTOR(SQObjectPtr,func->_noutervalues,nc->_outervalues);
_CONSTRUCT_VECTOR(SQObjectPtr,func->_ndefaultparams,nc->_defaultparams);
return nc;
}
void Release(){
SQFunctionProto *f = _function;
SQInteger size = _CALC_CLOSURE_SIZE(f);
_DESTRUCT_VECTOR(SQObjectPtr,f->_noutervalues,_outervalues);
_DESTRUCT_VECTOR(SQObjectPtr,f->_ndefaultparams,_defaultparams);
__ObjRelease(_function);
this->~SQClosure();
sq_vm_free(this,size);
}
void SetRoot(SQWeakRef *r)
{
__ObjRelease(_root);
_root = r;
__ObjAddRef(_root);
}
SQClosure *Clone()
{
SQFunctionProto *f = _function;
SQClosure * ret = SQClosure::Create(NULL,f,_root);
ret->_env = _env;
if(ret->_env) __ObjAddRef(ret->_env);
_COPY_VECTOR(ret->_outervalues,_outervalues,f->_noutervalues);
_COPY_VECTOR(ret->_defaultparams,_defaultparams,f->_ndefaultparams);
return ret;
}
~SQClosure();
bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
SQWeakRef *_env;
SQWeakRef *_root;
SQClass *_base;
SQFunctionProto *_function;
SQObjectPtr *_outervalues;
SQObjectPtr *_defaultparams;
bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
SQWeakRef *_env;
SQWeakRef *_root;
SQClass *_base;
SQFunctionProto *_function;
SQObjectPtr *_outervalues;
SQObjectPtr *_defaultparams;
};
//////////////////////////////////////////////
@ -70,60 +70,60 @@ struct SQOuter : public CHAINABLE_OBJ
{
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:
static SQOuter *Create(SQSharedState *ss, SQObjectPtr *outer)
{
SQOuter *nc = (SQOuter*)SQ_MALLOC(sizeof(SQOuter));
new (nc) SQOuter(ss, outer);
return nc;
}
~SQOuter() { REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); }
static SQOuter *Create(SQSharedState *ss, SQObjectPtr *outer)
{
SQOuter *nc = (SQOuter*)SQ_MALLOC(sizeof(SQOuter));
new (nc) SQOuter(ss, outer);
return nc;
}
~SQOuter() { REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); }
void Release()
{
this->~SQOuter();
sq_vm_free(this,sizeof(SQOuter));
}
void Release()
{
this->~SQOuter();
sq_vm_free(this,sizeof(SQOuter));
}
SQObjectPtr *_valptr; /* pointer to value on stack, or _value below */
SQInteger _idx; /* idx in stack array, for relocation */
SQObjectPtr _value; /* value of outer after stack frame is closed */
SQOuter *_next; /* pointer to next outer when frame is open */
SQObjectPtr *_valptr; /* pointer to value on stack, or _value below */
SQInteger _idx; /* idx in stack array, for relocation */
SQObjectPtr _value; /* value of outer after stack frame is closed */
SQOuter *_next; /* pointer to next outer when frame is open */
};
//////////////////////////////////////////////
struct SQGenerator : public CHAINABLE_OBJ
{
enum SQGeneratorState{eRunning,eSuspended,eDead};
enum SQGeneratorState{eRunning,eSuspended,eDead};
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:
static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){
SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));
new (nc) SQGenerator(ss,closure);
return nc;
}
~SQGenerator()
{
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
}
void Kill(){
_state=eDead;
_stack.resize(0);
_closure.Null();}
void Release(){
sq_delete(this,SQGenerator);
}
static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){
SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));
new (nc) SQGenerator(ss,closure);
return nc;
}
~SQGenerator()
{
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
}
void Kill(){
_state=eDead;
_stack.resize(0);
_closure.Null();}
void Release(){
sq_delete(this,SQGenerator);
}
bool Yield(SQVM *v,SQInteger target);
bool Resume(SQVM *v,SQObjectPtr &dest);
SQObjectPtr _closure;
SQObjectPtrVec _stack;
SQVM::CallInfo _ci;
ExceptionsTraps _etraps;
SQGeneratorState _state;
bool Yield(SQVM *v,SQInteger target);
bool Resume(SQVM *v,SQObjectPtr &dest);
SQObjectPtr _closure;
SQObjectPtrVec _stack;
SQVM::CallInfo _ci;
ExceptionsTraps _etraps;
SQGeneratorState _state;
};
#define _CALC_NATVIVECLOSURE_SIZE(noutervalues) (sizeof(SQNativeClosure) + (noutervalues*sizeof(SQObjectPtr)))
@ -131,48 +131,48 @@ public:
struct SQNativeClosure : public CHAINABLE_OBJ
{
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:
static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func,SQInteger nouters)
{
SQInteger size = _CALC_NATVIVECLOSURE_SIZE(nouters);
SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(size);
new (nc) SQNativeClosure(ss,func);
nc->_outervalues = (SQObjectPtr *)(nc + 1);
nc->_noutervalues = nouters;
_CONSTRUCT_VECTOR(SQObjectPtr,nc->_noutervalues,nc->_outervalues);
return nc;
}
SQNativeClosure *Clone()
{
SQNativeClosure * ret = SQNativeClosure::Create(NULL,_function,_noutervalues);
ret->_env = _env;
if(ret->_env) __ObjAddRef(ret->_env);
ret->_name = _name;
_COPY_VECTOR(ret->_outervalues,_outervalues,_noutervalues);
ret->_typecheck.copy(_typecheck);
ret->_nparamscheck = _nparamscheck;
return ret;
}
~SQNativeClosure()
{
__ObjRelease(_env);
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
}
void Release(){
SQInteger size = _CALC_NATVIVECLOSURE_SIZE(_noutervalues);
_DESTRUCT_VECTOR(SQObjectPtr,_noutervalues,_outervalues);
this->~SQNativeClosure();
sq_free(this,size);
}
static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func,SQInteger nouters)
{
SQInteger size = _CALC_NATVIVECLOSURE_SIZE(nouters);
SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(size);
new (nc) SQNativeClosure(ss,func);
nc->_outervalues = (SQObjectPtr *)(nc + 1);
nc->_noutervalues = nouters;
_CONSTRUCT_VECTOR(SQObjectPtr,nc->_noutervalues,nc->_outervalues);
return nc;
}
SQNativeClosure *Clone()
{
SQNativeClosure * ret = SQNativeClosure::Create(NULL,_function,_noutervalues);
ret->_env = _env;
if(ret->_env) __ObjAddRef(ret->_env);
ret->_name = _name;
_COPY_VECTOR(ret->_outervalues,_outervalues,_noutervalues);
ret->_typecheck.copy(_typecheck);
ret->_nparamscheck = _nparamscheck;
return ret;
}
~SQNativeClosure()
{
__ObjRelease(_env);
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
}
void Release(){
SQInteger size = _CALC_NATVIVECLOSURE_SIZE(_noutervalues);
_DESTRUCT_VECTOR(SQObjectPtr,_noutervalues,_outervalues);
this->~SQNativeClosure();
sq_free(this,size);
}
SQInteger _nparamscheck;
SQIntVec _typecheck;
SQObjectPtr *_outervalues;
SQUnsignedInteger _noutervalues;
SQWeakRef *_env;
SQFUNCTION _function;
SQObjectPtr _name;
SQInteger _nparamscheck;
SQIntVec _typecheck;
SQObjectPtr *_outervalues;
SQUnsignedInteger _noutervalues;
SQWeakRef *_env;
SQFUNCTION _function;
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_STRING_LITERAL 259
#define TK_INTEGER 260
#define TK_FLOAT 261
#define TK_FLOAT 261
#define TK_BASE 262
#define TK_DELETE 263
#define TK_EQ 264
@ -20,13 +20,13 @@ struct SQVM;
#define TK_LE 266
#define TK_GE 267
#define TK_SWITCH 268
#define TK_ARROW 269
#define TK_ARROW 269
#define TK_AND 270
#define TK_OR 271
#define TK_IF 272
#define TK_ELSE 273
#define TK_WHILE 274
#define TK_BREAK 275
#define TK_WHILE 274
#define TK_BREAK 275
#define TK_FOR 276
#define TK_DO 277
#define TK_NULL 278
@ -34,8 +34,8 @@ struct SQVM;
#define TK_IN 280
#define TK_NEWSLOT 281
#define TK_MODULO 282
#define TK_LOCAL 283
#define TK_CLONE 284
#define TK_LOCAL 283
#define TK_CLONE 284
#define TK_FUNCTION 285
#define TK_RETURN 286
#define TK_TYPEOF 287

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -16,41 +16,41 @@ struct SQTable;
struct SQStringTable
{
SQStringTable(SQSharedState*ss);
~SQStringTable();
SQString *Add(const SQChar *,SQInteger len);
void Remove(SQString *);
SQStringTable(SQSharedState*ss);
~SQStringTable();
SQString *Add(const SQChar *,SQInteger len);
void Remove(SQString *);
private:
void Resize(SQInteger size);
void AllocNodes(SQInteger size);
SQString **_strings;
SQUnsignedInteger _numofslots;
SQUnsignedInteger _slotused;
SQSharedState *_sharedstate;
void Resize(SQInteger size);
void AllocNodes(SQInteger size);
SQString **_strings;
SQUnsignedInteger _numofslots;
SQUnsignedInteger _slotused;
SQSharedState *_sharedstate;
};
struct RefTable {
struct RefNode {
SQObjectPtr obj;
SQUnsignedInteger refs;
struct RefNode *next;
};
RefTable();
~RefTable();
void AddRef(SQObject &obj);
SQBool Release(SQObject &obj);
SQUnsignedInteger GetRefCount(SQObject &obj);
void Finalize();
struct RefNode {
SQObjectPtr obj;
SQUnsignedInteger refs;
struct RefNode *next;
};
RefTable();
~RefTable();
void AddRef(SQObject &obj);
SQBool Release(SQObject &obj);
SQUnsignedInteger GetRefCount(SQObject &obj);
void Finalize();
private:
RefNode *Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add);
RefNode *Add(SQHash mainpos,SQObject &obj);
void Resize(SQUnsignedInteger size);
void AllocNodes(SQUnsignedInteger size);
SQUnsignedInteger _numofslots;
SQUnsignedInteger _slotused;
RefNode *_nodes;
RefNode *_freelist;
RefNode **_buckets;
RefNode *Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add);
RefNode *Add(SQHash mainpos,SQObject &obj);
void Resize(SQUnsignedInteger size);
void AllocNodes(SQUnsignedInteger size);
SQUnsignedInteger _numofslots;
SQUnsignedInteger _slotused;
RefNode *_nodes;
RefNode *_freelist;
RefNode **_buckets;
};
#define ADD_STRING(ss,str,len) ss->_stringtable->Add(str,len)
@ -60,66 +60,66 @@ struct SQObjectPtr;
struct SQSharedState
{
SQSharedState();
~SQSharedState();
void Init();
SQSharedState();
~SQSharedState();
void Init();
public:
SQChar* GetScratchPad(SQInteger size);
SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name);
SQObjectPtrVec *_metamethods;
SQObjectPtr _metamethodsmap;
SQObjectPtrVec *_systemstrings;
SQObjectPtrVec *_types;
SQStringTable *_stringtable;
RefTable _refs_table;
SQObjectPtr _registry;
SQObjectPtr _consts;
SQObjectPtr _constructoridx;
SQObjectPtr _root_vm;
SQObjectPtr _table_default_delegate;
static const SQRegFunction _table_default_delegate_funcz[];
SQObjectPtr _array_default_delegate;
static const SQRegFunction _array_default_delegate_funcz[];
SQObjectPtr _string_default_delegate;
static const SQRegFunction _string_default_delegate_funcz[];
SQObjectPtr _number_default_delegate;
static const SQRegFunction _number_default_delegate_funcz[];
SQObjectPtr _generator_default_delegate;
static const SQRegFunction _generator_default_delegate_funcz[];
SQObjectPtr _closure_default_delegate;
static const SQRegFunction _closure_default_delegate_funcz[];
SQObjectPtr _thread_default_delegate;
static const SQRegFunction _thread_default_delegate_funcz[];
SQObjectPtr _class_default_delegate;
static const SQRegFunction _class_default_delegate_funcz[];
SQObjectPtr _instance_default_delegate;
static const SQRegFunction _instance_default_delegate_funcz[];
SQObjectPtr _weakref_default_delegate;
static const SQRegFunction _weakref_default_delegate_funcz[];
SQChar* GetScratchPad(SQInteger size);
SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name);
SQObjectPtrVec *_metamethods;
SQObjectPtr _metamethodsmap;
SQObjectPtrVec *_systemstrings;
SQObjectPtrVec *_types;
SQStringTable *_stringtable;
RefTable _refs_table;
SQObjectPtr _registry;
SQObjectPtr _consts;
SQObjectPtr _constructoridx;
SQObjectPtr _root_vm;
SQObjectPtr _table_default_delegate;
static const SQRegFunction _table_default_delegate_funcz[];
SQObjectPtr _array_default_delegate;
static const SQRegFunction _array_default_delegate_funcz[];
SQObjectPtr _string_default_delegate;
static const SQRegFunction _string_default_delegate_funcz[];
SQObjectPtr _number_default_delegate;
static const SQRegFunction _number_default_delegate_funcz[];
SQObjectPtr _generator_default_delegate;
static const SQRegFunction _generator_default_delegate_funcz[];
SQObjectPtr _closure_default_delegate;
static const SQRegFunction _closure_default_delegate_funcz[];
SQObjectPtr _thread_default_delegate;
static const SQRegFunction _thread_default_delegate_funcz[];
SQObjectPtr _class_default_delegate;
static const SQRegFunction _class_default_delegate_funcz[];
SQObjectPtr _instance_default_delegate;
static const SQRegFunction _instance_default_delegate_funcz[];
SQObjectPtr _weakref_default_delegate;
static const SQRegFunction _weakref_default_delegate_funcz[];
SQCOMPILERERROR _compilererrorhandler;
SQPRINTFUNCTION _printfunc;
SQPRINTFUNCTION _errorfunc;
bool _debuginfo;
bool _notifyallexceptions;
SQUserPointer _foreignptr;
SQRELEASEHOOK _releasehook;
SQCOMPILERERROR _compilererrorhandler;
SQPRINTFUNCTION _printfunc;
SQPRINTFUNCTION _errorfunc;
bool _debuginfo;
bool _notifyallexceptions;
SQUserPointer _foreignptr;
SQRELEASEHOOK _releasehook;
private:
SQChar *_scratchpad;
SQInteger _scratchpadsize;
SQChar *_scratchpad;
SQInteger _scratchpadsize;
};
#define _sp(s) (_sharedstate->GetScratchPad(s))
#define _spval (_sharedstate->GetScratchPad(-1))
#define _table_ddel _table(_sharedstate->_table_default_delegate)
#define _array_ddel _table(_sharedstate->_array_default_delegate)
#define _string_ddel _table(_sharedstate->_string_default_delegate)
#define _number_ddel _table(_sharedstate->_number_default_delegate)
#define _table_ddel _table(_sharedstate->_table_default_delegate)
#define _array_ddel _table(_sharedstate->_array_default_delegate)
#define _string_ddel _table(_sharedstate->_string_default_delegate)
#define _number_ddel _table(_sharedstate->_number_default_delegate)
#define _generator_ddel _table(_sharedstate->_generator_default_delegate)
#define _closure_ddel _table(_sharedstate->_closure_default_delegate)
#define _thread_ddel _table(_sharedstate->_thread_default_delegate)
#define _class_ddel _table(_sharedstate->_class_default_delegate)
#define _thread_ddel _table(_sharedstate->_thread_default_delegate)
#define _class_ddel _table(_sharedstate->_class_default_delegate)
#define _instance_ddel _table(_sharedstate->_instance_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)
{
SQHash h = (SQHash)l; /* seed */
size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */
for (; l>=step; l-=step)
h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++));
return h;
SQHash h = (SQHash)l; /* seed */
size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */
for (; l>=step; l-=step)
h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++));
return h;
}
struct SQString : public SQRefCounted
{
SQString(){}
~SQString(){}
SQString(){}
~SQString(){}
public:
static SQString *Create(SQSharedState *ss, const SQChar *, SQInteger len = -1 );
SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
void Release();
SQSharedState *_sharedstate;
SQString *_next; //chain for the string table
SQInteger _len;
SQHash _hash;
SQChar _val[1];
static SQString *Create(SQSharedState *ss, const SQChar *, SQInteger len = -1 );
SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
void Release();
SQSharedState *_sharedstate;
SQString *_next; //chain for the string table
SQInteger _len;
SQHash _hash;
SQChar _val[1];
};

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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