From 8ad48d9343c0ca3e3cd8d7afa5dd4f913d1784aa Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Thu, 20 Apr 2017 08:20:48 +0200 Subject: [PATCH] app_sqlang: new module offering a Kemi interpreter for Squirrel language - squirrel language engine is embedded to avoid external dependencies - squirrel is a small scripting language targeting embedded usage, compiling the scripts in memory - the module can reload the script at runtime via rpc command --- src/modules/app_sqlang/Makefile | 21 + src/modules/app_sqlang/README | 259 + src/modules/app_sqlang/app_sqlang_api.c | 1584 +++ src/modules/app_sqlang/app_sqlang_api.h | 47 + .../app_sqlang/app_sqlang_kemi_export.c | 9283 +++++++++++++++++ .../app_sqlang/app_sqlang_kemi_export.h | 42 + src/modules/app_sqlang/app_sqlang_mod.c | 582 ++ src/modules/app_sqlang/doc/Makefile | 4 + src/modules/app_sqlang/doc/app_sqlang.xml | 36 + .../app_sqlang/doc/app_sqlang_admin.xml | 288 + .../app_sqlang/squirrel/include/sqconfig.h | 146 + .../app_sqlang/squirrel/include/sqstdaux.h | 16 + .../app_sqlang/squirrel/include/sqstdblob.h | 20 + .../app_sqlang/squirrel/include/sqstdio.h | 53 + .../app_sqlang/squirrel/include/sqstdmath.h | 15 + .../app_sqlang/squirrel/include/sqstdstring.h | 33 + .../app_sqlang/squirrel/include/sqstdsystem.h | 15 + .../app_sqlang/squirrel/include/squirrel.h | 405 + .../app_sqlang/squirrel/sqstdlib/Makefile | 41 + .../app_sqlang/squirrel/sqstdlib/sqstdaux.cpp | 130 + .../squirrel/sqstdlib/sqstdblob.cpp | 277 + .../squirrel/sqstdlib/sqstdblobimpl.h | 108 + .../app_sqlang/squirrel/sqstdlib/sqstdio.cpp | 485 + .../app_sqlang/squirrel/sqstdlib/sqstdlib.dsp | 131 + .../squirrel/sqstdlib/sqstdmath.cpp | 107 + .../app_sqlang/squirrel/sqstdlib/sqstdrex.cpp | 663 ++ .../squirrel/sqstdlib/sqstdstream.cpp | 336 + .../squirrel/sqstdlib/sqstdstream.h | 18 + .../squirrel/sqstdlib/sqstdstring.cpp | 501 + .../squirrel/sqstdlib/sqstdsystem.cpp | 146 + .../app_sqlang/squirrel/squirrel/Makefile | 52 + .../app_sqlang/squirrel/squirrel/sqapi.cpp | 1602 +++ .../app_sqlang/squirrel/squirrel/sqarray.h | 94 + .../squirrel/squirrel/sqbaselib.cpp | 1266 +++ .../app_sqlang/squirrel/squirrel/sqclass.cpp | 210 + .../app_sqlang/squirrel/squirrel/sqclass.h | 162 + .../app_sqlang/squirrel/squirrel/sqclosure.h | 201 + .../squirrel/squirrel/sqcompiler.cpp | 1578 +++ .../app_sqlang/squirrel/squirrel/sqcompiler.h | 78 + .../app_sqlang/squirrel/squirrel/sqdebug.cpp | 118 + .../squirrel/squirrel/sqfuncproto.h | 154 + .../squirrel/squirrel/sqfuncstate.cpp | 653 ++ .../squirrel/squirrel/sqfuncstate.h | 91 + .../app_sqlang/squirrel/squirrel/sqlexer.cpp | 561 + .../app_sqlang/squirrel/squirrel/sqlexer.h | 55 + .../app_sqlang/squirrel/squirrel/sqmem.cpp | 11 + .../app_sqlang/squirrel/squirrel/sqobject.cpp | 677 ++ .../app_sqlang/squirrel/squirrel/sqobject.h | 354 + .../app_sqlang/squirrel/squirrel/sqopcodes.h | 132 + .../app_sqlang/squirrel/squirrel/sqpcheader.h | 20 + .../app_sqlang/squirrel/squirrel/sqstate.cpp | 657 ++ .../app_sqlang/squirrel/squirrel/sqstate.h | 136 + .../app_sqlang/squirrel/squirrel/sqstring.h | 31 + .../app_sqlang/squirrel/squirrel/sqtable.cpp | 221 + .../app_sqlang/squirrel/squirrel/sqtable.h | 110 + .../app_sqlang/squirrel/squirrel/squirrel.dsp | 302 + .../app_sqlang/squirrel/squirrel/squserdata.h | 40 + .../app_sqlang/squirrel/squirrel/squtils.h | 116 + .../app_sqlang/squirrel/squirrel/sqvm.cpp | 1748 ++++ .../app_sqlang/squirrel/squirrel/sqvm.h | 214 + src/modules/app_sqlang/utils/app_sqlang_ctl | 143 + 61 files changed, 27579 insertions(+) create mode 100644 src/modules/app_sqlang/Makefile create mode 100644 src/modules/app_sqlang/README create mode 100644 src/modules/app_sqlang/app_sqlang_api.c create mode 100644 src/modules/app_sqlang/app_sqlang_api.h create mode 100644 src/modules/app_sqlang/app_sqlang_kemi_export.c create mode 100644 src/modules/app_sqlang/app_sqlang_kemi_export.h create mode 100644 src/modules/app_sqlang/app_sqlang_mod.c create mode 100644 src/modules/app_sqlang/doc/Makefile create mode 100644 src/modules/app_sqlang/doc/app_sqlang.xml create mode 100644 src/modules/app_sqlang/doc/app_sqlang_admin.xml create mode 100644 src/modules/app_sqlang/squirrel/include/sqconfig.h create mode 100644 src/modules/app_sqlang/squirrel/include/sqstdaux.h create mode 100644 src/modules/app_sqlang/squirrel/include/sqstdblob.h create mode 100644 src/modules/app_sqlang/squirrel/include/sqstdio.h create mode 100644 src/modules/app_sqlang/squirrel/include/sqstdmath.h create mode 100644 src/modules/app_sqlang/squirrel/include/sqstdstring.h create mode 100644 src/modules/app_sqlang/squirrel/include/sqstdsystem.h create mode 100644 src/modules/app_sqlang/squirrel/include/squirrel.h create mode 100644 src/modules/app_sqlang/squirrel/sqstdlib/Makefile create mode 100644 src/modules/app_sqlang/squirrel/sqstdlib/sqstdaux.cpp create mode 100644 src/modules/app_sqlang/squirrel/sqstdlib/sqstdblob.cpp create mode 100644 src/modules/app_sqlang/squirrel/sqstdlib/sqstdblobimpl.h create mode 100644 src/modules/app_sqlang/squirrel/sqstdlib/sqstdio.cpp create mode 100644 src/modules/app_sqlang/squirrel/sqstdlib/sqstdlib.dsp create mode 100644 src/modules/app_sqlang/squirrel/sqstdlib/sqstdmath.cpp create mode 100644 src/modules/app_sqlang/squirrel/sqstdlib/sqstdrex.cpp create mode 100644 src/modules/app_sqlang/squirrel/sqstdlib/sqstdstream.cpp create mode 100644 src/modules/app_sqlang/squirrel/sqstdlib/sqstdstream.h create mode 100644 src/modules/app_sqlang/squirrel/sqstdlib/sqstdstring.cpp create mode 100644 src/modules/app_sqlang/squirrel/sqstdlib/sqstdsystem.cpp create mode 100644 src/modules/app_sqlang/squirrel/squirrel/Makefile create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqapi.cpp create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqarray.h create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqbaselib.cpp create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqclass.cpp create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqclass.h create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqclosure.h create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqcompiler.cpp create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqcompiler.h create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqdebug.cpp create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqfuncproto.h create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.cpp create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.h create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqlexer.cpp create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqlexer.h create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqmem.cpp create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqobject.cpp create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqobject.h create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqopcodes.h create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqpcheader.h create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqstate.cpp create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqstate.h create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqstring.h create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqtable.cpp create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqtable.h create mode 100644 src/modules/app_sqlang/squirrel/squirrel/squirrel.dsp create mode 100644 src/modules/app_sqlang/squirrel/squirrel/squserdata.h create mode 100644 src/modules/app_sqlang/squirrel/squirrel/squtils.h create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqvm.cpp create mode 100644 src/modules/app_sqlang/squirrel/squirrel/sqvm.h create mode 100755 src/modules/app_sqlang/utils/app_sqlang_ctl diff --git a/src/modules/app_sqlang/Makefile b/src/modules/app_sqlang/Makefile new file mode 100644 index 00000000000..129a93eba7a --- /dev/null +++ b/src/modules/app_sqlang/Makefile @@ -0,0 +1,21 @@ +# +# app_sqlang module makefile +# +# WARNING: do not run this directly, it should be run by the master Makefile + +include ../../Makefile.defs +auto_gen= +NAME=app_sqlang.so + +DEFS+=-DKAMAILIO_MOD_INTERFACE -I./squirrel/include +LIBS += -L. -lsquirrel -lsqstdlib + +include ../../Makefile.modules + +libsquirrel.a: + make -C ./squirrel/squirrel + +libsqstdlib.a: + make -C ./squirrel/sqstdlib + +app_sqlang.so: libsquirrel.a libsqstdlib.a diff --git a/src/modules/app_sqlang/README b/src/modules/app_sqlang/README new file mode 100644 index 00000000000..6d48ce5ff7e --- /dev/null +++ b/src/modules/app_sqlang/README @@ -0,0 +1,259 @@ +app_sqlang Module + +Daniel-Constantin Mierla + + asipto.com + +Edited by + +Daniel-Constantin Mierla + + + + Copyright © 2017 Daniel-Constantin Mierla (asipto.com) + __________________________________________________________________ + + Table of Contents + + 1. Admin Guide + + 1. Overview + 2. Dependencies + + 2.1. Kamailio Modules + 2.2. External Libraries or Applications + + 3. Parameters + + 3.1. load (str) + + 4. Functions + + 4.1. sqlang_dofile(path) + 4.2. sqlang_dostring(script) + 4.3. sqlang_run(function [, params]) + 4.4. sqlang_runstring(script) + + 5. RPC Commands + + 5.1. app_swlang.reload + 5.2. app_sqlang.api_list + + 6. Example of usage + + List of Examples + + 1.1. Set load parameter + 1.2. sqlang_dofile usage + 1.3. sqlang_dostring usage + 1.4. sqlang_run usage + 1.5. sqlang_runstring usage + +Chapter 1. Admin Guide + + Table of Contents + + 1. Overview + 2. Dependencies + + 2.1. Kamailio Modules + 2.2. External Libraries or Applications + + 3. Parameters + + 3.1. load (str) + + 4. Functions + + 4.1. sqlang_dofile(path) + 4.2. sqlang_dostring(script) + 4.3. sqlang_run(function [, params]) + 4.4. sqlang_runstring(script) + + 5. RPC Commands + + 5.1. app_swlang.reload + 5.2. app_sqlang.api_list + + 6. Example of usage + +1. Overview + + This module allows executing Squirrel Language (SQLang) scripts from + config file. It exports all KEMI functions to SQLang in order to access + the current processed SIP message. These functions are within SQLang + object 'KSR' (a table object). + + It includes the Squirrel Language engine + (http://www.squirrel-lang.org). Exported API from SIP router to SQLang + is documented in the dokuwiki. + + The module has two SQLang contexts: + * first is used for functions sqlang_dofile() and sqlang_dostring(). + * second is used for function sqlan_run() and parameter 'load'. + Therefore sqlang_run() cannot execute functions from scripts loaded + via sqlang_dofile() in config. This is kind of caching mode, + avoiding reading file every time, but you must be sure you do not + have someting that is executed by default and requires access to + SIP message. This environment is also used by KEMI framework for + the config SIP routing functions. + +2. Dependencies + + 2.1. Kamailio Modules + 2.2. External Libraries or Applications + +2.1. Kamailio Modules + + The following modules must be loaded before this module: + * none. + +2.2. External Libraries or Applications + + The following libraries or applications must be installed before + running Kamailio with this module loaded: + * none + +3. Parameters + + 3.1. load (str) + +3.1. load (str) + + Set the path to the SQLang file to be loaded at startup. Then you can + use sqlang_run(function, params) to execute a function from the script + at runtime. If you use it for KEMI configuration, then it has to + include the requited functions. + + Default value is "null". + + Example 1.1. Set load parameter +... +modparam("app_sqlang", "load", "/usr/local/etc/kamailio/sqlang/myscript.sq") +... + +4. Functions + + 4.1. sqlang_dofile(path) + 4.2. sqlang_dostring(script) + 4.3. sqlang_run(function [, params]) + 4.4. sqlang_runstring(script) + +4.1. sqlang_dofile(path) + + Note: not implemented yet. + + Execute the SQLang script stored in 'path'. The parameter can be a + string with pseudo-variables evaluated at runtime. + + Example 1.2. sqlang_dofile usage +... +sqlang_dofile("/usr/local/etc/kamailio/sqlang/myscript.sq"); +... + +4.2. sqlang_dostring(script) + + Note: not implemented yet. + + Execute the Lua script stored in parameter. The parameter can be a + string with pseudo-variables. + + Example 1.3. sqlang_dostring usage +... +if(!sqlang_dostring('KSR.dbg("test message\n")')) +{ + xdbg("SCRIPT: failed to execute js script!\n"); +} +... + +4.3. sqlang_run(function [, params]) + + Execute the JS function 'func' giving params as parameters. There can + be up to 3 string parameters. The function must exist in the script + loaded at startup via parameter 'load'. Parameters can be strings with + pseudo-variables that are evaluated at runtime. + + Example 1.4. sqlang_run usage +... +if(!sqlang_run("js_append_fu_to_reply")) +{ + xdbg("SCRIPT: failed to execute js function!\n"); +} +... +sqlang_run("js_funcx", "$rU", "2"); +... + +4.4. sqlang_runstring(script) + + Note: not implemented yet. + + Execute the SQLang script stored in parameter. The parameter can be a + string with pseudo-variables. The script is executed in JS context + specific to loaded JS files at startup. + + Example 1.5. sqlang_runstring usage +... +if(!sqlang_runstring('KSR.dbg("Hello World from $fU\n")')) +{ + xdbg("failed to execute js script!\n"); +} +... + +5. RPC Commands + + 5.1. app_swlang.reload + 5.2. app_sqlang.api_list + +5.1. app_swlang.reload + + Marks the need to reload the SQLang script pointed by 'load' + parameter.The actual reload is done by every working process when the + next call to sqlang_run() function or KEMI config is executed. + + Name: app_sqlang.reload + + Parameters: none + + Example: +... +kamcmd app_sqlang.reload +... + +5.2. app_sqlang.api_list + + List the functions available via Kemi framework. + + Name: app_sqlang.api_list + + Parameters: none + + Example: +... +kamcmd app_sqlang.api_list +... + +6. Example of usage + + Create your SQLang script and stored on file system, say: + '/usr/local/etc/kamailio/sqlang/myscript.sq'. +... +function sr_append_fu_to_reply() +{ + KSR.hdr.append_to_reply("P-From: " + KSR.pv.get("$fu") + "\r\n"); +} +... + + Load the script via parameter 'load' and execute function via + sqlang_run(...). +... +modparam("app_sqlang", "load", "/usr/local/etc/kamailio/sqlang/myscript.sq") +... +request_route { + ... + if(!sqlang_run("sr_append_fu_to_reply")) + { + xdbg("SCRIPT: failed to execute js function!\n"); + } + ... +} +... diff --git a/src/modules/app_sqlang/app_sqlang_api.c b/src/modules/app_sqlang/app_sqlang_api.c new file mode 100644 index 00000000000..d5e3f865a7b --- /dev/null +++ b/src/modules/app_sqlang/app_sqlang_api.c @@ -0,0 +1,1584 @@ +/** + * Copyright (C) 2017 Daniel-Constantin Mierla (asipto.com) + * + * This file is part of Kamailio, a free SIP server. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version + * + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include + +#include "../../core/dprint.h" +#include "../../core/pvar.h" +#include "../../core/sr_module.h" +#include "../../core/mem/shm.h" +#include "../../core/rpc.h" +#include "../../core/rpc_lookup.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "app_sqlang_kemi_export.h" +#include "app_sqlang_api.h" + +#define SRSQLANG_FALSE 0 +#define SRSQLANG_TRUE 1 + +void sqlang_sr_kemi_register_libs(HSQUIRRELVM J); + +typedef struct _sr_sqlang_env +{ + HSQUIRRELVM J; + HSQUIRRELVM JJ; + sip_msg_t *msg; + unsigned int flags; + unsigned int nload; /* number of scripts loaded */ +} sr_sqlang_env_t; + +static sr_sqlang_env_t _sr_J_env = {0}; + +str _sr_sqlang_load_file = STR_NULL; + +static int *_sr_sqlang_reload_version = NULL; +static int _sr_sqlang_local_version = 0; + +/** + * + */ +sr_sqlang_env_t *sqlang_sr_env_get(void) +{ + return &_sr_J_env; +} + +/** + * + */ +int sqlang_sr_initialized(void) +{ + if(_sr_J_env.J==NULL) + return 0; + + return 1; +} + +/** + * + */ +#define SQLANG_SR_EXIT_THROW_STR "~~ksr~exit~~" +#define SQLANG_SR_EXIT_EXEC_STR "throw '" SQLANG_SR_EXIT_THROW_STR "';" + +static str _sr_kemi_sqlang_exit_string = str_init(SQLANG_SR_EXIT_THROW_STR); + +/** + * + */ +str* sr_kemi_sqlang_exit_string_get(void) +{ + return &_sr_kemi_sqlang_exit_string; +} + +/** + * + */ +int app_sqlang_return_int(HSQUIRRELVM J, int v) +{ + sq_pushinteger(J, v); + return 1; +} + +/** + * + */ +int app_sqlang_return_error(HSQUIRRELVM J) +{ + sq_pushinteger(J, -1); + return 1; +} + +/** + * + */ +int app_sqlang_return_boolean(HSQUIRRELVM J, int b) +{ + if(b==SRSQLANG_FALSE) + sq_pushbool(J, SRSQLANG_FALSE); + else + sq_pushbool(J, SRSQLANG_TRUE); + return 1; +} + +/** + * + */ +int app_sqlang_return_false(HSQUIRRELVM J) +{ + sq_pushbool(J, SRSQLANG_FALSE); + return 1; +} + +/** + * + */ +int app_sqlang_return_true(HSQUIRRELVM J) +{ + sq_pushbool(J, SRSQLANG_TRUE); + return 1; +} + +/** + * + */ +int sr_kemi_sqlang_return_int(HSQUIRRELVM J, sr_kemi_t *ket, int rc) +{ + if(ket->rtype==SR_KEMIP_INT) { + sq_pushinteger(J, rc); + return 1; + } + if(ket->rtype==SR_KEMIP_BOOL && rc!=SR_KEMI_FALSE) { + return app_sqlang_return_true(J); + } + return app_sqlang_return_false(J); +} + +static char* sqlang_to_string(HSQUIRRELVM J, int idx) +{ + const SQChar *s = NULL; + if(idx>=0) { + sq_getstring(J, idx+2, &s); + } else { + sq_getstring(J, idx, &s); + } + return (char*)s; +} + +static int sqlang_to_int(HSQUIRRELVM J, int idx) +{ + SQInteger i = 0; + + if(idx>=0) { + sq_getinteger(J, idx+2, &i); + } else { + sq_getinteger(J, idx, &i); + } + return (int)i; +} + +static int sqlang_gettop(HSQUIRRELVM J) +{ + return (sq_gettop(J) - 1); +} + +static void sqlang_pushstring(HSQUIRRELVM J, char *s) +{ + if(s==NULL) { + sq_pushnull(J); + return; + } + sq_pushstring(J, (const SQChar*)s, (SQInteger)strlen(s)); +} + +static void sqlang_pushlstring(HSQUIRRELVM J, char *s, int l) +{ + if(s==NULL) { + sq_pushnull(J); + return; + } + sq_pushstring(J, (const SQChar*)s, (SQInteger)l); +} + +static int sqlang_isnumber(HSQUIRRELVM J, int idx) +{ + if(idx>=0) { + idx += 2; + } + + if(sq_gettype(J, idx)==OT_INTEGER) + return 1; + return 0; +} + +static int sqlang_isstring(HSQUIRRELVM J, int idx) +{ + if(idx>=0) { + idx += 2; + } + + if(sq_gettype(J, idx)==OT_STRING) + return 1; + return 0; +} + +static int sqlang_isfunction(HSQUIRRELVM J, int idx) +{ + if(idx>=0) { + idx += 2; + } + + switch(sq_gettype(J, idx)) { + case OT_CLOSURE: + case OT_NATIVECLOSURE: + return 1; + default: + return 0; + } +} + +static char* sqlang_safe_tostring(HSQUIRRELVM J, int idx) +{ + return "Error on sqlang"; +} + +static int sqlang_gettype(HSQUIRRELVM J, int idx) +{ + if(idx>=0) { + idx += 2; + } + + return (int)sq_gettype(J, idx); +} + +/** + * + */ +static SQInteger sqlang_sr_pv_get(HSQUIRRELVM J) +{ + str pvn; + pv_spec_t *pvs; + pv_value_t val; + sr_sqlang_env_t *env_J; + int pl; + + env_J = sqlang_sr_env_get(); + + pvn.s = (char*)sqlang_to_string(J, 0); + if(pvn.s==NULL || env_J->msg==NULL) + return 0; + + pvn.len = strlen(pvn.s); + LM_DBG("pv get: %s\n", pvn.s); + pl = pv_locate_name(&pvn); + if(pl != pvn.len) { + LM_ERR("invalid pv [%s] (%d/%d)\n", pvn.s, pl, pvn.len); + return 0; + } + pvs = pv_cache_get(&pvn); + if(pvs==NULL) { + LM_ERR("cannot get pv spec for [%s]\n", pvn.s); + return 0; + } + memset(&val, 0, sizeof(pv_value_t)); + if(pv_get_spec_value(env_J->msg, pvs, &val) != 0) { + LM_ERR("unable to get pv value for [%s]\n", pvn.s); + return 0; + } + if(val.flags&PV_VAL_NULL) { + sqlang_pushstring(J, NULL); + return 1; + } + if(val.flags&PV_TYPE_INT) { + sq_pushinteger(J, (SQInteger)val.ri); + return 1; + } + sqlang_pushlstring(J, val.rs.s, val.rs.len); + return 1; +} + +/** + * + */ +static SQInteger sqlang_sr_pv_seti (HSQUIRRELVM J) +{ + str pvn; + pv_spec_t *pvs; + pv_value_t val; + sr_sqlang_env_t *env_J; + int pl; + + env_J = sqlang_sr_env_get(); + + if(sqlang_gettop(J)<2) { + LM_ERR("too few parameters [%d]\n", sqlang_gettop(J)); + return 0; + } + if(!sqlang_isnumber(J, 1)) { + LM_ERR("invalid int parameter\n"); + return 0; + } + + pvn.s = (char*)sqlang_to_string(J, 0); + if(pvn.s==NULL || env_J->msg==NULL) + return 0; + + pvn.len = strlen(pvn.s); + LM_DBG("pv get: %s\n", pvn.s); + pl = pv_locate_name(&pvn); + if(pl != pvn.len) { + LM_ERR("invalid pv [%s] (%d/%d)\n", pvn.s, pl, pvn.len); + return 0; + } + pvs = pv_cache_get(&pvn); + if(pvs==NULL) { + LM_ERR("cannot get pv spec for [%s]\n", pvn.s); + return 0; + } + + memset(&val, 0, sizeof(pv_value_t)); + val.ri = sqlang_to_int(J, 1); + val.flags |= PV_TYPE_INT|PV_VAL_INT; + + if(pv_set_spec_value(env_J->msg, pvs, 0, &val)<0) { + LM_ERR("unable to set pv [%s]\n", pvn.s); + return 0; + } + + return 0; +} + +/** + * + */ +static SQInteger sqlang_sr_pv_sets (HSQUIRRELVM J) +{ + str pvn; + pv_spec_t *pvs; + pv_value_t val; + sr_sqlang_env_t *env_J; + int pl; + + env_J = sqlang_sr_env_get(); + + if(sqlang_gettop(J)<2) { + LM_ERR("too few parameters [%d]\n", sqlang_gettop(J)); + return 0; + } + + if(!sqlang_isstring(J, 1)) { + LM_ERR("invalid str parameter\n"); + return 0; + } + + pvn.s = (char*)sqlang_to_string(J, 0); + if(pvn.s==NULL || env_J->msg==NULL) + return 0; + + memset(&val, 0, sizeof(pv_value_t)); + val.rs.s = (char*)sqlang_to_string(J, 1); + val.rs.len = strlen(val.rs.s); + val.flags |= PV_VAL_STR; + + pvn.len = strlen(pvn.s); + LM_DBG("pv set: %s\n", pvn.s); + pl = pv_locate_name(&pvn); + if(pl != pvn.len) { + LM_ERR("invalid pv [%s] (%d/%d)\n", pvn.s, pl, pvn.len); + return 0; + } + pvs = pv_cache_get(&pvn); + if(pvs==NULL) { + LM_ERR("cannot get pv spec for [%s]\n", pvn.s); + return 0; + } + if(pv_set_spec_value(env_J->msg, pvs, 0, &val)<0) { + LM_ERR("unable to set pv [%s]\n", pvn.s); + return 0; + } + + return 0; +} + +/** + * + */ +static SQInteger sqlang_sr_pv_unset (HSQUIRRELVM J) +{ + str pvn; + pv_spec_t *pvs; + pv_value_t val; + sr_sqlang_env_t *env_J; + int pl; + + env_J = sqlang_sr_env_get(); + + pvn.s = (char*)sqlang_to_string(J, 0); + if(pvn.s==NULL || env_J->msg==NULL) + return 0; + + pvn.len = strlen(pvn.s); + LM_DBG("pv unset: %s\n", pvn.s); + pl = pv_locate_name(&pvn); + if(pl != pvn.len) { + LM_ERR("invalid pv [%s] (%d/%d)\n", pvn.s, pl, pvn.len); + return 0; + } + pvs = pv_cache_get(&pvn); + if(pvs==NULL) + { + LM_ERR("cannot get pv spec for [%s]\n", pvn.s); + return 0; + } + memset(&val, 0, sizeof(pv_value_t)); + val.flags |= PV_VAL_NULL; + if(pv_set_spec_value(env_J->msg, pvs, 0, &val)<0) + { + LM_ERR("unable to unset pv [%s]\n", pvn.s); + return 0; + } + + return 0; +} + +/** + * + */ +static SQInteger sqlang_sr_pv_is_null (HSQUIRRELVM J) +{ + str pvn; + pv_spec_t *pvs; + pv_value_t val; + sr_sqlang_env_t *env_J; + int pl; + + env_J = sqlang_sr_env_get(); + + pvn.s = (char*)sqlang_to_string(J, 0); + if(pvn.s==NULL || env_J->msg==NULL) + return 0; + + pvn.len = strlen(pvn.s); + LM_DBG("pv is null test: %s\n", pvn.s); + pl = pv_locate_name(&pvn); + if(pl != pvn.len) { + LM_ERR("invalid pv [%s] (%d/%d)\n", pvn.s, pl, pvn.len); + return 0; + } + pvs = pv_cache_get(&pvn); + if(pvs==NULL) { + LM_ERR("cannot get pv spec for [%s]\n", pvn.s); + return 0; + } + memset(&val, 0, sizeof(pv_value_t)); + if(pv_get_spec_value(env_J->msg, pvs, &val) != 0) { + LM_NOTICE("unable to get pv value for [%s]\n", pvn.s); + sq_pushbool(J, 1); + return 1; + } + if(val.flags&PV_VAL_NULL) { + sq_pushbool(J, 1); + } else { + sq_pushbool(J, 0); + } + return 1; +} + + +const SQRegFunction _sr_kemi_pv_J_Map[] = { + { "get", sqlang_sr_pv_get, 2 /* 1 args */, NULL }, + { "seti", sqlang_sr_pv_seti, 3 /* 2 args */, NULL }, + { "sets", sqlang_sr_pv_sets, 4 /* 2 args */, NULL }, + { "unset", sqlang_sr_pv_unset, 2 /* 1 args */, NULL }, + { "is_null", sqlang_sr_pv_is_null, 2 /* 1 args */, NULL }, + { NULL, NULL, 0 } +}; + +/** + * + */ +static SQInteger sqlang_sr_exit (HSQUIRRELVM J) +{ + return sq_throwerror(J, _SC("~~ksr~exit~~")); +} + +/** + * + */ +static SQInteger sqlang_sr_drop (HSQUIRRELVM J) +{ + sr_kemi_core_drop(NULL); + return sq_throwerror(J, _SC("~~ksr~exit~~")); +} + + +/** + * + */ +static SQInteger sqlang_sr_modf (HSQUIRRELVM J) +{ + int ret; + char *sqlangv[MAX_ACTIONS]; + char *argv[MAX_ACTIONS]; + int argc; + int i; + int mod_type; + struct run_act_ctx ra_ctx; + unsigned modver; + struct action *act; + sr31_cmd_export_t* expf; + sr_sqlang_env_t *env_J; + + ret = 1; + act = NULL; + argc = 0; + memset(sqlangv, 0, MAX_ACTIONS*sizeof(char*)); + memset(argv, 0, MAX_ACTIONS*sizeof(char*)); + env_J = sqlang_sr_env_get(); + if(env_J->msg==NULL) + goto error; + + argc = sqlang_gettop(J); + if(argc==0) { + LM_ERR("name of module function not provided\n"); + goto error; + } + if(argc>=MAX_ACTIONS) { + LM_ERR("too many parameters\n"); + goto error; + } + /* first is function name, then parameters */ + for(i=0; ifixup!=NULL && expf->free_fixup==NULL) { + LM_ERR("function '%s' has fixup - cannot be used\n", sqlangv[0]); + goto error; + } + switch(expf->param_no) { + case 0: + mod_type = MODULE0_T; + break; + case 1: + mod_type = MODULE1_T; + break; + case 2: + mod_type = MODULE2_T; + break; + case 3: + mod_type = MODULE3_T; + break; + case 4: + mod_type = MODULE4_T; + break; + case 5: + mod_type = MODULE5_T; + break; + case 6: + mod_type = MODULE6_T; + break; + case VAR_PARAM_NO: + mod_type = MODULEX_T; + break; + default: + LM_ERR("unknown/bad definition for function '%s' (%d params)\n", + sqlangv[0], expf->param_no); + goto error; + } + + act = mk_action(mod_type, argc+1 /* number of (type, value) pairs */, + MODEXP_ST, expf, /* function */ + NUMBER_ST, argc-1, /* parameter number */ + STRING_ST, argv[1], /* param. 1 */ + STRING_ST, argv[2], /* param. 2 */ + STRING_ST, argv[3], /* param. 3 */ + STRING_ST, argv[4], /* param. 4 */ + STRING_ST, argv[5], /* param. 5 */ + STRING_ST, argv[6] /* param. 6 */ + ); + + if (act==NULL) { + LM_ERR("action structure could not be created for '%s'\n", sqlangv[0]); + goto error; + } + + /* handle fixups */ + if (expf->fixup) { + if(argc==1) { + /* no parameters */ + if(expf->fixup(0, 0)<0) { + LM_ERR("Error in fixup (0) for '%s'\n", sqlangv[0]); + goto error; + } + } else { + for(i=1; ifixup(&(act->val[i+1].u.data), i)<0) { + LM_ERR("Error in fixup (%d) for '%s'\n", i, sqlangv[0]); + goto error; + } + act->val[i+1].type = MODFIXUP_ST; + } + } + } + init_run_actions_ctx(&ra_ctx); + ret = do_action(&ra_ctx, act, env_J->msg); + + /* free fixups */ + if (expf->fixup) { + for(i=1; ival[i+1].type == MODFIXUP_ST) && (act->val[i+1].u.data)) { + expf->free_fixup(&(act->val[i+1].u.data), i); + } + } + } + pkg_free(act); + for(i=0; i0) { + buf[len] = '\0'; + if(!SQ_SUCCEEDED(sq_compilebuffer(J, buf, len, + _SC(filename), SQTrue))) { + LM_ERR("failed to compile: %s\n", filename); + return -1; + } + } else { + LM_ERR("empty content in %s\n", filename); + return -1; + } + } else { + LM_ERR("cannot open file: %s\n", filename); + return -1; + } + return 0; +#endif +} + +/** + * + */ +int sqlang_sr_init_mod(void) +{ + if(_sr_sqlang_reload_version == NULL) { + _sr_sqlang_reload_version = (int*)shm_malloc(sizeof(int)); + if(_sr_sqlang_reload_version == NULL) { + LM_ERR("failed to allocated reload version\n"); + return -1; + } + *_sr_sqlang_reload_version = 0; + } + memset(&_sr_J_env, 0, sizeof(sr_sqlang_env_t)); + + return 0; +} + +/** + * + */ +int sqlang_kemi_load_script(void) +{ + if(sqlang_load_file(_sr_J_env.JJ, _sr_sqlang_load_file.s)<0) { + LM_ERR("failed to load sqlang script file: %.*s\n", + _sr_sqlang_load_file.len, _sr_sqlang_load_file.s); + return -1; + } + return 0; +} +/** + * + */ +int sqlang_sr_init_child(void) +{ + memset(&_sr_J_env, 0, sizeof(sr_sqlang_env_t)); + _sr_J_env.J = sq_open(1024); + if(_sr_J_env.J==NULL) { + LM_ERR("cannot create SQlang context (exec)\n"); + return -1; + } + sq_pushroottable(_sr_J_env.J); + /*sets the print functions*/ + sq_setprintfunc(_sr_J_env.J, sqlang_printfunc, sqlang_errorfunc); + //sq_setnativedebughook(_sr_J_env.J, sqlang_debughook); + sq_enabledebuginfo(_sr_J_env.J, 1); + + sqstd_register_bloblib(_sr_J_env.J); + sqstd_register_iolib(_sr_J_env.J); + sqstd_register_systemlib(_sr_J_env.J); + sqstd_register_mathlib(_sr_J_env.J); + sqstd_register_stringlib(_sr_J_env.J); + sqstd_seterrorhandlers(_sr_J_env.J); + + sqlang_sr_kemi_register_libs(_sr_J_env.J); + if(_sr_sqlang_load_file.s != NULL && _sr_sqlang_load_file.len>0) { + _sr_J_env.JJ = sq_open(1024); + if(_sr_J_env.JJ==NULL) { + LM_ERR("cannot create load SQLang context (load)\n"); + return -1; + } + sq_pushroottable(_sr_J_env.JJ); + LM_DBG("*** sqlang top index now is: %d\n", (int)sqlang_gettop(_sr_J_env.JJ)); + /*sets the print functions*/ + sq_setprintfunc(_sr_J_env.JJ, sqlang_printfunc, sqlang_errorfunc); + //sq_setnativedebughook(_sr_J_env.JJ, sqlang_debughook); + sq_enabledebuginfo(_sr_J_env.JJ, 1); + + sqstd_register_bloblib(_sr_J_env.JJ); + sqstd_register_iolib(_sr_J_env.JJ); + sqstd_register_systemlib(_sr_J_env.JJ); + sqstd_register_mathlib(_sr_J_env.JJ); + sqstd_register_stringlib(_sr_J_env.JJ); + sqstd_seterrorhandlers(_sr_J_env.JJ); + + sqlang_sr_kemi_register_libs(_sr_J_env.JJ); + LM_DBG("loading sqlang script file: %.*s\n", + _sr_sqlang_load_file.len, _sr_sqlang_load_file.s); + if(sqlang_kemi_load_script()<0) { + return -1; + } + } + LM_DBG("JS initialized!\n"); + return 0; +} + +/** + * + */ +void sqlang_sr_destroy(void) +{ + if(_sr_J_env.J!=NULL) { + sq_close(_sr_J_env.J); + _sr_J_env.J = NULL; + } + if(_sr_J_env.JJ!=NULL) { + sq_close(_sr_J_env.JJ); + _sr_J_env.JJ = NULL; + } + memset(&_sr_J_env, 0, sizeof(sr_sqlang_env_t)); +} + +/** + * + */ +int sqlang_kemi_reload_script(void) +{ + int v; + if(_sr_sqlang_load_file.s == NULL && _sr_sqlang_load_file.len<=0) { + LM_WARN("script file path not provided\n"); + return -1; + } + if(_sr_sqlang_reload_version == NULL) { + LM_WARN("reload not enabled\n"); + return -1; + } + if(_sr_J_env.JJ==NULL) { + LM_ERR("load JS context not created\n"); + return -1; + } + + v = *_sr_sqlang_reload_version; + if(v == _sr_sqlang_local_version) { + /* same version */ + return 0; + } + LM_DBG("reloading sqlang script file: %.*s (%d => %d)\n", + _sr_sqlang_load_file.len, _sr_sqlang_load_file.s, + _sr_sqlang_local_version, v); + sqlang_kemi_load_script(); + _sr_sqlang_local_version = v; + return 0; +} + + +/** + * + */ +int app_sqlang_run_ex(sip_msg_t *msg, char *func, char *p1, char *p2, + char *p3, int emode) +{ + int n; + int ret; + str txt; + int top; + sip_msg_t *bmsg; + SQInteger rv; + + if(_sr_J_env.JJ==NULL) { + LM_ERR("sqlang loading state not initialized (call: %s)\n", func); + return -1; + } + /* check the script version loaded */ + sqlang_kemi_reload_script(); + + top = sqlang_gettop(_sr_J_env.JJ); + + LM_DBG("sqlang top index is: %d\n", top); + sq_pushroottable(_sr_J_env.JJ); /* pushes the global table */ + sq_pushstring(_sr_J_env.JJ, _SC(func), -1); + if(!SQ_SUCCEEDED(sq_get(_sr_J_env.JJ, -2))) { + /* failed to gets the func field from the global table */ + sq_settop(_sr_J_env.JJ, (top<=0)?1:top); /* restores the original stack size */ + LM_ERR("sqlang failed to find symbol (call: %s)\n", func); + return -1; + } + + if(!sqlang_isfunction(_sr_J_env.JJ, -1)) + { + LM_ERR("no such function [%s] in sqlang scripts\n", func); + LM_ERR("top stack type [%d]\n", + sqlang_gettype(_sr_J_env.JJ, -1)); + } + /* push the 'this' (in this case is the global table) */ + sq_pushroottable(_sr_J_env.JJ); + n = 1; + if(p1!=NULL) + { + sqlang_pushstring(_sr_J_env.JJ, p1); + n++; + if(p2!=NULL) + { + sqlang_pushstring(_sr_J_env.JJ, p2); + n++; + if(p3!=NULL) + { + sqlang_pushstring(_sr_J_env.JJ, p3); + n++; + } + } + } + LM_DBG("executing sqlang function: [[%s]] (n: %d)\n", func, n); + bmsg = _sr_J_env.msg; + _sr_J_env.msg = msg; + /* call the function */ + rv = sq_call(_sr_J_env.JJ, n, SQFalse, SQTrue); + if(SQ_SUCCEEDED(rv)) { + ret = 1; + } else { + LM_ERR("failed to execute the func: %s (%d)\n", func, (int)rv); + sqstd_printcallstack(_sr_J_env.JJ); + ret = -1; + } + _sr_J_env.msg = bmsg; + sq_settop(_sr_J_env.JJ, (top<=0)?1:top); /* restores the original stack size */ + + return ret; +} + +/** + * + */ +int app_sqlang_run(sip_msg_t *msg, char *func, char *p1, char *p2, + char *p3) +{ + return app_sqlang_run_ex(msg, func, p1, p2, p3, 1); +} + +/** + * + */ +int app_sqlang_runstring(sip_msg_t *msg, char *script) +{ +#if 0 + int ret; + sip_msg_t *bmsg; + + if(_sr_J_env.JJ==NULL) { + LM_ERR("sqlang loading state not initialized (call: %s)\n", script); + return -1; + } + + sqlang_kemi_reload_script(); + + LM_DBG("running sqlang string: [[%s]]\n", script); + LM_DBG("sqlang top index is: %d\n", sqlang_gettop(_sr_J_env.JJ)); + bmsg = _sr_J_env.msg; + _sr_J_env.msg = msg; + sqlang_pushstring(_sr_J_env.JJ, script); + ret = duk_peval(_sr_J_env.JJ); + if(ret != 0) { + LM_ERR("JS failed running: %s\n", sqlang_safe_tostring(_sr_J_env.JJ, -1)); + } + duk_pop(_sr_J_env.JJ); /* ignore result */ + + _sr_J_env.msg = bmsg; + return (ret==0)?1:-1; +#endif + LM_ERR("not implemented\n"); + return -1; +} + +/** + * + */ +int app_sqlang_dostring(sip_msg_t *msg, char *script) +{ +#if 0 + int ret; + sip_msg_t *bmsg; + + LM_DBG("executing sqlang string: [[%s]]\n", script); + LM_DBG("JS top index is: %d\n", sqlang_gettop(_sr_J_env.J)); + bmsg = _sr_J_env.msg; + _sr_J_env.msg = msg; + sqlang_pushstring(_sr_J_env.J, script); + ret = duk_peval(_sr_J_env.J); + if(ret != 0) { + LM_ERR("JS failed running: %s\n", sqlang_safe_tostring(_sr_J_env.J, -1)); + } + duk_pop(_sr_J_env.J); /* ignore result */ + _sr_J_env.msg = bmsg; + return (ret==0)?1:-1; +#endif + LM_ERR("not implemented\n"); + return -1; +} + +/** + * + */ +int app_sqlang_dofile(sip_msg_t *msg, char *script) +{ +#if 0 + int ret; + sip_msg_t *bmsg; + + LM_DBG("executing sqlang file: [[%s]]\n", script); + LM_DBG("JS top index is: %d\n", sqlang_gettop(_sr_J_env.J)); + bmsg = _sr_J_env.msg; + _sr_J_env.msg = msg; + if(sqlang_load_file(_sr_J_env.J, script)<0) { + LM_ERR("failed to load sqlang script file: %s\n", script); + return -1; + } + ret = duk_peval(_sr_J_env.J); + if(ret != 0) { + LM_ERR("JS failed running: %s\n", sqlang_safe_tostring(_sr_J_env.J, -1)); + } + duk_pop(_sr_J_env.J); /* ignore result */ + + _sr_J_env.msg = bmsg; + return (ret==0)?1:-1; +#endif + LM_ERR("not implemented\n"); + return -1; +} + +/** + * + */ +int sr_kemi_sqlang_exec_func_ex(HSQUIRRELVM J, sr_kemi_t *ket) +{ + int i; + int argc; + int ret; + str *fname; + str *mname; + sr_kemi_val_t vps[SR_KEMI_PARAMS_MAX]; + sr_sqlang_env_t *env_J; + + env_J = sqlang_sr_env_get(); + + if(env_J==NULL || env_J->msg==NULL || ket==NULL) { + LM_ERR("invalid JS environment attributes or parameters\n"); + return app_sqlang_return_false(J); + } + + fname = &ket->fname; + mname = &ket->mname; + + argc = sqlang_gettop(J); + if(argc==0 && ket->ptypes[0]==SR_KEMIP_NONE) { + ret = ((sr_kemi_fm_f)(ket->func))(env_J->msg); + return sr_kemi_sqlang_return_int(J, ket, ret); + } + if(argc==0 && ket->ptypes[0]!=SR_KEMIP_NONE) { + LM_ERR("invalid number of parameters for: %.*s.%.*s\n", + mname->len, mname->s, fname->len, fname->s); + return app_sqlang_return_false(J); + } + + if(argc>SR_KEMI_PARAMS_MAX) { + LM_ERR("too many parameters for: %.*s.%.*s\n", + mname->len, mname->s, fname->len, fname->s); + return app_sqlang_return_false(J); + } + + memset(vps, 0, SR_KEMI_PARAMS_MAX*sizeof(sr_kemi_val_t)); + for(i=0; iptypes[i]==SR_KEMIP_NONE) { + break; + } else if(ket->ptypes[i]==SR_KEMIP_STR) { + vps[i].s.s = (char*)sqlang_to_string(J, i); + vps[i].s.len = strlen(vps[i].s.s); + LM_DBG("param[%d] for: %.*s is str: %.*s\n", i, + fname->len, fname->s, vps[i].s.len, vps[i].s.s); + } else if(ket->ptypes[i]==SR_KEMIP_INT) { + vps[i].n = sqlang_to_int(J, i); + LM_DBG("param[%d] for: %.*s is int: %d\n", i, + fname->len, fname->s, vps[i].n); + } else { + LM_ERR("unknown parameter type %d (%d)\n", ket->ptypes[i], i); + return app_sqlang_return_false(J); + } + } + + switch(i) { + case 1: + if(ket->ptypes[0]==SR_KEMIP_INT) { + ret = ((sr_kemi_fmn_f)(ket->func))(env_J->msg, vps[0].n); + return sr_kemi_sqlang_return_int(J, ket, ret); + } else if(ket->ptypes[0]==SR_KEMIP_STR) { + ret = ((sr_kemi_fms_f)(ket->func))(env_J->msg, &vps[0].s); + return sr_kemi_sqlang_return_int(J, ket, ret); + } else { + LM_ERR("invalid parameters for: %.*s\n", + fname->len, fname->s); + return app_sqlang_return_false(J); + } + break; + case 2: + if(ket->ptypes[0]==SR_KEMIP_INT) { + if(ket->ptypes[1]==SR_KEMIP_INT) { + ret = ((sr_kemi_fmnn_f)(ket->func))(env_J->msg, vps[0].n, vps[1].n); + return sr_kemi_sqlang_return_int(J, ket, ret); + } else if(ket->ptypes[1]==SR_KEMIP_STR) { + ret = ((sr_kemi_fmns_f)(ket->func))(env_J->msg, vps[0].n, &vps[1].s); + return sr_kemi_sqlang_return_int(J, ket, ret); + } else { + LM_ERR("invalid parameters for: %.*s\n", + fname->len, fname->s); + return app_sqlang_return_false(J); + } + } else if(ket->ptypes[0]==SR_KEMIP_STR) { + if(ket->ptypes[1]==SR_KEMIP_INT) { + ret = ((sr_kemi_fmsn_f)(ket->func))(env_J->msg, &vps[0].s, vps[1].n); + return sr_kemi_sqlang_return_int(J, ket, ret); + } else if(ket->ptypes[1]==SR_KEMIP_STR) { + ret = ((sr_kemi_fmss_f)(ket->func))(env_J->msg, &vps[0].s, &vps[1].s); + return sr_kemi_sqlang_return_int(J, ket, ret); + } else { + LM_ERR("invalid parameters for: %.*s\n", + fname->len, fname->s); + return app_sqlang_return_false(J); + } + } else { + LM_ERR("invalid parameters for: %.*s\n", + fname->len, fname->s); + return app_sqlang_return_false(J); + } + break; + case 3: + if(ket->ptypes[0]==SR_KEMIP_INT) { + if(ket->ptypes[1]==SR_KEMIP_INT) { + if(ket->ptypes[2]==SR_KEMIP_INT) { + ret = ((sr_kemi_fmnnn_f)(ket->func))(env_J->msg, + vps[0].n, vps[1].n, vps[2].n); + return sr_kemi_sqlang_return_int(J, ket, ret); + } else if(ket->ptypes[2]==SR_KEMIP_STR) { + ret = ((sr_kemi_fmnns_f)(ket->func))(env_J->msg, + vps[0].n, vps[1].n, &vps[2].s); + return sr_kemi_sqlang_return_int(J, ket, ret); + } else { + LM_ERR("invalid parameters for: %.*s\n", + fname->len, fname->s); + return app_sqlang_return_false(J); + } + } else if(ket->ptypes[1]==SR_KEMIP_STR) { + if(ket->ptypes[2]==SR_KEMIP_INT) { + ret = ((sr_kemi_fmnsn_f)(ket->func))(env_J->msg, + vps[0].n, &vps[1].s, vps[2].n); + return sr_kemi_sqlang_return_int(J, ket, ret); + } else if(ket->ptypes[2]==SR_KEMIP_STR) { + ret = ((sr_kemi_fmnss_f)(ket->func))(env_J->msg, + vps[0].n, &vps[1].s, &vps[2].s); + return sr_kemi_sqlang_return_int(J, ket, ret); + } else { + LM_ERR("invalid parameters for: %.*s\n", + fname->len, fname->s); + return app_sqlang_return_false(J); + } + } else { + LM_ERR("invalid parameters for: %.*s\n", + fname->len, fname->s); + return app_sqlang_return_false(J); + } + } else if(ket->ptypes[0]==SR_KEMIP_STR) { + if(ket->ptypes[1]==SR_KEMIP_INT) { + if(ket->ptypes[2]==SR_KEMIP_INT) { + ret = ((sr_kemi_fmsnn_f)(ket->func))(env_J->msg, + &vps[0].s, vps[1].n, vps[2].n); + return sr_kemi_sqlang_return_int(J, ket, ret); + } else if(ket->ptypes[2]==SR_KEMIP_STR) { + ret = ((sr_kemi_fmsns_f)(ket->func))(env_J->msg, + &vps[0].s, vps[1].n, &vps[2].s); + return sr_kemi_sqlang_return_int(J, ket, ret); + } else { + LM_ERR("invalid parameters for: %.*s\n", + fname->len, fname->s); + return app_sqlang_return_false(J); + } + } else if(ket->ptypes[1]==SR_KEMIP_STR) { + if(ket->ptypes[2]==SR_KEMIP_INT) { + ret = ((sr_kemi_fmssn_f)(ket->func))(env_J->msg, + &vps[0].s, &vps[1].s, vps[2].n); + return sr_kemi_sqlang_return_int(J, ket, ret); + } else if(ket->ptypes[2]==SR_KEMIP_STR) { + ret = ((sr_kemi_fmsss_f)(ket->func))(env_J->msg, + &vps[0].s, &vps[1].s, &vps[2].s); + return sr_kemi_sqlang_return_int(J, ket, ret); + } else { + LM_ERR("invalid parameters for: %.*s\n", + fname->len, fname->s); + return app_sqlang_return_false(J); + } + } else { + LM_ERR("invalid parameters for: %.*s\n", + fname->len, fname->s); + return app_sqlang_return_false(J); + } + } else { + LM_ERR("invalid parameters for: %.*s\n", + fname->len, fname->s); + return app_sqlang_return_false(J); + } + break; + case 4: + if(ket->ptypes[0]==SR_KEMIP_STR + || ket->ptypes[1]==SR_KEMIP_STR + || ket->ptypes[2]==SR_KEMIP_STR + || ket->ptypes[3]==SR_KEMIP_STR) { + ret = ((sr_kemi_fmssss_f)(ket->func))(env_J->msg, + &vps[0].s, &vps[1].s, &vps[2].s, &vps[3].s); + return sr_kemi_sqlang_return_int(J, ket, ret); + } else if(ket->ptypes[0]==SR_KEMIP_STR + || ket->ptypes[1]==SR_KEMIP_STR + || ket->ptypes[2]==SR_KEMIP_INT + || ket->ptypes[3]==SR_KEMIP_INT) { + ret = ((sr_kemi_fmssnn_f)(ket->func))(env_J->msg, + &vps[0].s, &vps[1].s, vps[2].n, vps[3].n); + return sr_kemi_sqlang_return_int(J, ket, ret); + } else { + LM_ERR("invalid parameters for: %.*s\n", + fname->len, fname->s); + return app_sqlang_return_false(J); + } + break; + case 5: + if(ket->ptypes[0]==SR_KEMIP_STR + || ket->ptypes[1]==SR_KEMIP_STR + || ket->ptypes[2]==SR_KEMIP_STR + || ket->ptypes[3]==SR_KEMIP_STR + || ket->ptypes[4]==SR_KEMIP_STR) { + ret = ((sr_kemi_fmsssss_f)(ket->func))(env_J->msg, + &vps[0].s, &vps[1].s, &vps[2].s, &vps[3].s, + &vps[4].s); + return sr_kemi_sqlang_return_int(J, ket, ret); + } else { + LM_ERR("invalid parameters for: %.*s\n", + fname->len, fname->s); + return app_sqlang_return_false(J); + } + break; + case 6: + if(ket->ptypes[0]==SR_KEMIP_STR + || ket->ptypes[1]==SR_KEMIP_STR + || ket->ptypes[2]==SR_KEMIP_STR + || ket->ptypes[3]==SR_KEMIP_STR + || ket->ptypes[4]==SR_KEMIP_STR + || ket->ptypes[5]==SR_KEMIP_STR) { + ret = ((sr_kemi_fmssssss_f)(ket->func))(env_J->msg, + &vps[0].s, &vps[1].s, &vps[2].s, &vps[3].s, + &vps[4].s, &vps[5].s); + return sr_kemi_sqlang_return_int(J, ket, ret); + } else { + LM_ERR("invalid parameters for: %.*s\n", + fname->len, fname->s); + return app_sqlang_return_false(J); + } + break; + default: + LM_ERR("invalid parameters for: %.*s\n", + fname->len, fname->s); + return app_sqlang_return_false(J); + } + return app_sqlang_return_false(J); +} + +/** + * + */ +int sr_kemi_sqlang_exec_func(HSQUIRRELVM J, int eidx) +{ + sr_kemi_t *ket; + + ket = sr_kemi_sqlang_export_get(eidx); + return sr_kemi_sqlang_exec_func_ex(J, ket); +} + +/** + * + */ +SQRegFunction *_sr_J_KSRMethods = NULL; +#define SR_SQLANG_KSR_MODULES_SIZE 256 +#define SR_SQLANG_KSR_METHODS_SIZE (SR_KEMI_SQLANG_EXPORT_SIZE + SR_SQLANG_KSR_MODULES_SIZE) + + +/** + * + */ +SQInteger sqlang_register_global_func(HSQUIRRELVM J, SQFUNCTION f, char *fname) +{ + sq_pushstring(J, fname, -1); + sq_newclosure(J, f, 0); /* create a new function */ + sq_newslot(J, -3, SQFalse); + return 0; +} + +/** + * + */ +SQInteger sqlang_open_KSR(HSQUIRRELVM J) +{ + SQRegFunction *_sr_crt_J_KSRMethods = NULL; + sr_kemi_module_t *emods = NULL; + int emods_size = 0; + int i; + int k; + int n; + char mname[128]; + char malias[256]; + + _sr_J_KSRMethods = malloc(SR_SQLANG_KSR_METHODS_SIZE * sizeof(SQRegFunction)); + if(_sr_J_KSRMethods==NULL) { + LM_ERR("no more pkg memory\n"); + return 0; + } + memset(_sr_J_KSRMethods, 0, SR_SQLANG_KSR_METHODS_SIZE * sizeof(SQRegFunction)); + + emods_size = sr_kemi_modules_size_get(); + emods = sr_kemi_modules_get(); + + n = 0; + _sr_crt_J_KSRMethods = _sr_J_KSRMethods; + if(emods_size==0 || emods[0].kexp==NULL) { + LM_ERR("no kemi exports registered\n"); + return 0; + } + + sq_pushroottable(J); /* stack[1] */ + sq_pushstring(J, "KSR", -1); /* stack[2] */ + sq_newtable(J); /* stack[3] */ + + for(i=0; emods[0].kexp[i].func!=NULL; i++) { + LM_DBG("exporting KSR.%s(...)\n", emods[0].kexp[i].fname.s); + _sr_crt_J_KSRMethods[i].name = emods[0].kexp[i].fname.s; + _sr_crt_J_KSRMethods[i].f = + sr_kemi_sqlang_export_associate(&emods[0].kexp[i]); + if(_sr_crt_J_KSRMethods[i].f == NULL) { + LM_ERR("failed to associate kemi function with sqlang export\n"); + free(_sr_J_KSRMethods); + _sr_J_KSRMethods = NULL; + goto error; + } + _sr_crt_J_KSRMethods[i].nparamscheck = 0; + snprintf(malias, 254, "%s", emods[0].kexp[i].fname.s); + sqlang_register_global_func(J, _sr_crt_J_KSRMethods[i].f, malias); + n++; + } + + /* special modules - pv.get(...) can return int or str */ + sq_pushstring(J, "pv", -1); /* stack[4] */ + sq_newtable(J); /* stack[5] */ + i=0; + while(_sr_kemi_pv_J_Map[i].name!=0) { + snprintf(malias, 254, "%s", _sr_kemi_pv_J_Map[i].name); + sqlang_register_global_func(J, _sr_kemi_pv_J_Map[i].f, malias); + i++; + } + sq_newslot(J, -3, SQFalse); + sq_pushstring(J, "x", -1); /* stack[4] */ + sq_newtable(J); /* stack[5] */ + i=0; + while(_sr_kemi_x_J_Map[i].name!=0) { + snprintf(malias, 254, "%s", _sr_kemi_x_J_Map[i].name); + sqlang_register_global_func(J, _sr_kemi_x_J_Map[i].f, malias); + i++; + } + sq_newslot(J, -3, SQFalse); + + /* registered kemi modules */ + if(emods_size>1) { + for(k=1; kfault(ctx, 500, "No script file"); + return; + } + if(_sr_sqlang_reload_version == NULL) { + LM_WARN("reload not enabled\n"); + rpc->fault(ctx, 500, "Reload not enabled"); + return; + } + + v = *_sr_sqlang_reload_version; + LM_INFO("marking for reload sqlang script file: %.*s (%d => %d)\n", + _sr_sqlang_load_file.len, _sr_sqlang_load_file.s, + _sr_sqlang_local_version, v); + *_sr_sqlang_reload_version += 1; + + if (rpc->add(ctx, "{", &vh) < 0) { + rpc->fault(ctx, 500, "Server error"); + return; + } + rpc->struct_add(vh, "dd", + "old", v, + "new", *_sr_sqlang_reload_version); +} + +static const char* app_sqlang_rpc_api_list_doc[2] = { + "List kemi exports to sqlang", + 0 +}; + +static void app_sqlang_rpc_api_list(rpc_t* rpc, void* ctx) +{ + int i; + int n; + sr_kemi_t *ket; + void* th; + void* sh; + void* ih; + + if (rpc->add(ctx, "{", &th) < 0) { + rpc->fault(ctx, 500, "Internal error root reply"); + return; + } + n = 0; + for(i=0; istruct_add(th, "d[", + "msize", n, + "methods", &ih)<0) + { + rpc->fault(ctx, 500, "Internal error array structure"); + return; + } + for(i=0; istruct_add(ih, "{", "func", &sh)<0) { + rpc->fault(ctx, 500, "Internal error internal structure"); + return; + } + if(rpc->struct_add(sh, "SSSS", + "ret", sr_kemi_param_map_get_name(ket->rtype), + "module", &ket->mname, + "name", &ket->fname, + "params", sr_kemi_param_map_get_params(ket->ptypes))<0) { + LM_ERR("failed to add the structure with attributes (%d)\n", i); + rpc->fault(ctx, 500, "Internal error creating dest struct"); + return; + } + } +} + +rpc_export_t app_sqlang_rpc_cmds[] = { + {"app_sqlang.reload", app_sqlang_rpc_reload, + app_sqlang_rpc_reload_doc, 0}, + {"app_sqlang.api_list", app_sqlang_rpc_api_list, + app_sqlang_rpc_api_list_doc, 0}, + {0, 0, 0, 0} +}; + +/** + * register RPC commands + */ +int app_sqlang_init_rpc(void) +{ + if (rpc_register_array(app_sqlang_rpc_cmds)!=0) + { + LM_ERR("failed to register RPC commands\n"); + return -1; + } + return 0; +} diff --git a/src/modules/app_sqlang/app_sqlang_api.h b/src/modules/app_sqlang/app_sqlang_api.h new file mode 100644 index 00000000000..31c824a99df --- /dev/null +++ b/src/modules/app_sqlang/app_sqlang_api.h @@ -0,0 +1,47 @@ +/** + * Copyright (C) 2017 Daniel-Constantin Mierla (asipto.com) + * + * This file is part of Kamailio, a free SIP server. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version + * + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef _APP_JSDT_API_H_ +#define _APP_JSDT_API_H_ + +#include + +#include "../../core/parser/msg_parser.h" + +int sqlang_sr_init_mod(void); +int sqlang_sr_init_child(void); +void sqlang_sr_destroy(void); + +int sqlang_sr_initialized(void); + +int sr_kemi_sqlang_exec_func(HSQUIRRELVM J, int eidx); + +int app_sqlang_run_ex(sip_msg_t *msg, char *func, char *p1, char *p2, + char *p3, int emode); +int app_sqlang_run(sip_msg_t *msg, char *func, char *p1, char *p2, + char *p3); +int app_sqlang_runstring(sip_msg_t *msg, char *script); +int app_sqlang_dostring(sip_msg_t *msg, char *script); +int app_sqlang_dofile(sip_msg_t *msg, char *script); + +int app_sqlang_init_rpc(void); +#endif diff --git a/src/modules/app_sqlang/app_sqlang_kemi_export.c b/src/modules/app_sqlang/app_sqlang_kemi_export.c new file mode 100644 index 00000000000..52a79df9a3e --- /dev/null +++ b/src/modules/app_sqlang/app_sqlang_kemi_export.c @@ -0,0 +1,9283 @@ +/** + * Copyright (C) 2016 Daniel-Constantin Mierla (asipto.com) + * + * This file is part of Kamailio, a free SIP server. + * + * Kamailio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version + * + * Kamailio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * this file is generated - do not edit + */ + +#include +#include +#include + +#include "../../core/dprint.h" + +#include "app_sqlang_api.h" +#include "app_sqlang_kemi_export.h" + + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_0(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 0); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_2(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 2); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_3(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 3); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_4(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 4); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_5(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 5); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_6(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 6); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_7(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 7); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_8(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 8); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_9(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 9); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_10(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 10); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_11(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 11); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_12(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 12); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_13(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 13); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_14(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 14); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_15(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 15); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_16(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 16); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_17(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 17); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_18(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 18); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_19(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 19); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_20(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 20); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_21(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 21); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_22(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 22); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_23(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 23); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_24(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 24); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_25(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 25); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_26(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 26); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_27(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 27); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_28(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 28); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_29(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 29); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_30(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 30); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_31(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 31); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_32(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 32); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_33(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 33); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_34(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 34); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_35(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 35); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_36(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 36); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_37(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 37); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_38(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 38); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_39(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 39); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_40(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 40); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_41(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 41); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_42(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 42); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_43(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 43); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_44(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 44); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_45(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 45); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_46(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 46); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_47(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 47); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_48(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 48); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_49(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 49); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_50(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 50); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_51(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 51); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_52(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 52); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_53(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 53); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_54(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 54); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_55(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 55); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_56(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 56); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_57(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 57); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_58(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 58); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_59(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 59); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_60(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 60); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_61(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 61); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_62(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 62); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_63(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 63); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_64(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 64); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_65(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 65); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_66(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 66); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_67(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 67); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_68(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 68); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_69(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 69); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_70(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 70); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_71(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 71); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_72(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 72); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_73(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 73); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_74(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 74); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_75(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 75); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_76(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 76); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_77(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 77); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_78(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 78); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_79(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 79); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_80(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 80); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_81(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 81); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_82(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 82); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_83(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 83); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_84(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 84); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_85(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 85); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_86(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 86); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_87(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 87); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_88(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 88); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_89(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 89); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_90(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 90); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_91(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 91); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_92(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 92); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_93(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 93); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_94(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 94); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_95(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 95); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_96(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 96); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_97(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 97); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_98(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 98); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_99(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 99); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_100(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 100); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_101(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 101); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_102(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 102); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_103(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 103); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_104(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 104); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_105(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 105); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_106(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 106); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_107(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 107); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_108(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 108); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_109(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 109); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_110(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 110); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_111(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 111); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_112(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 112); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_113(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 113); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_114(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 114); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_115(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 115); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_116(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 116); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_117(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 117); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_118(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 118); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_119(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 119); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_120(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 120); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_121(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 121); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_122(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 122); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_123(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 123); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_124(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 124); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_125(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 125); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_126(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 126); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_127(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 127); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_128(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 128); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_129(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 129); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_130(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 130); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_131(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 131); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_132(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 132); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_133(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 133); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_134(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 134); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_135(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 135); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_136(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 136); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_137(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 137); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_138(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 138); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_139(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 139); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_140(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 140); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_141(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 141); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_142(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 142); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_143(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 143); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_144(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 144); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_145(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 145); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_146(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 146); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_147(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 147); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_148(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 148); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_149(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 149); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_150(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 150); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_151(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 151); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_152(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 152); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_153(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 153); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_154(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 154); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_155(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 155); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_156(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 156); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_157(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 157); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_158(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 158); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_159(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 159); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_160(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 160); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_161(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 161); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_162(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 162); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_163(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 163); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_164(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 164); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_165(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 165); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_166(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 166); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_167(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 167); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_168(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 168); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_169(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 169); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_170(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 170); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_171(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 171); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_172(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 172); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_173(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 173); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_174(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 174); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_175(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 175); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_176(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 176); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_177(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 177); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_178(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 178); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_179(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 179); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_180(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 180); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_181(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 181); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_182(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 182); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_183(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 183); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_184(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 184); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_185(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 185); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_186(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 186); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_187(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 187); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_188(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 188); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_189(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 189); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_190(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 190); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_191(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 191); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_192(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 192); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_193(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 193); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_194(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 194); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_195(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 195); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_196(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 196); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_197(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 197); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_198(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 198); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_199(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 199); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_200(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 200); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_201(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 201); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_202(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 202); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_203(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 203); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_204(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 204); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_205(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 205); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_206(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 206); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_207(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 207); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_208(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 208); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_209(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 209); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_210(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 210); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_211(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 211); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_212(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 212); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_213(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 213); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_214(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 214); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_215(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 215); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_216(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 216); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_217(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 217); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_218(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 218); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_219(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 219); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_220(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 220); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_221(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 221); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_222(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 222); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_223(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 223); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_224(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 224); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_225(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 225); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_226(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 226); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_227(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 227); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_228(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 228); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_229(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 229); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_230(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 230); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_231(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 231); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_232(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 232); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_233(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 233); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_234(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 234); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_235(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 235); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_236(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 236); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_237(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 237); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_238(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 238); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_239(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 239); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_240(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 240); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_241(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 241); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_242(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 242); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_243(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 243); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_244(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 244); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_245(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 245); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_246(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 246); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_247(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 247); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_248(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 248); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_249(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 249); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_250(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 250); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_251(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 251); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_252(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 252); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_253(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 253); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_254(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 254); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_255(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 255); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_256(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 256); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_257(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 257); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_258(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 258); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_259(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 259); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_260(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 260); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_261(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 261); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_262(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 262); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_263(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 263); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_264(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 264); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_265(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 265); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_266(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 266); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_267(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 267); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_268(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 268); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_269(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 269); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_270(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 270); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_271(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 271); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_272(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 272); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_273(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 273); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_274(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 274); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_275(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 275); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_276(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 276); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_277(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 277); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_278(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 278); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_279(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 279); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_280(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 280); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_281(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 281); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_282(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 282); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_283(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 283); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_284(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 284); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_285(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 285); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_286(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 286); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_287(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 287); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_288(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 288); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_289(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 289); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_290(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 290); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_291(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 291); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_292(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 292); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_293(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 293); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_294(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 294); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_295(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 295); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_296(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 296); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_297(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 297); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_298(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 298); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_299(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 299); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_300(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 300); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_301(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 301); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_302(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 302); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_303(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 303); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_304(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 304); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_305(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 305); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_306(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 306); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_307(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 307); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_308(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 308); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_309(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 309); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_310(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 310); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_311(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 311); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_312(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 312); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_313(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 313); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_314(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 314); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_315(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 315); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_316(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 316); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_317(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 317); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_318(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 318); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_319(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 319); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_320(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 320); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_321(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 321); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_322(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 322); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_323(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 323); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_324(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 324); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_325(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 325); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_326(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 326); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_327(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 327); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_328(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 328); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_329(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 329); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_330(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 330); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_331(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 331); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_332(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 332); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_333(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 333); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_334(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 334); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_335(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 335); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_336(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 336); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_337(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 337); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_338(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 338); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_339(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 339); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_340(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 340); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_341(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 341); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_342(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 342); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_343(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 343); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_344(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 344); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_345(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 345); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_346(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 346); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_347(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 347); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_348(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 348); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_349(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 349); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_350(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 350); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_351(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 351); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_352(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 352); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_353(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 353); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_354(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 354); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_355(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 355); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_356(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 356); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_357(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 357); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_358(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 358); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_359(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 359); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_360(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 360); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_361(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 361); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_362(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 362); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_363(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 363); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_364(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 364); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_365(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 365); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_366(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 366); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_367(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 367); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_368(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 368); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_369(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 369); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_370(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 370); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_371(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 371); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_372(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 372); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_373(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 373); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_374(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 374); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_375(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 375); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_376(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 376); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_377(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 377); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_378(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 378); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_379(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 379); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_380(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 380); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_381(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 381); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_382(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 382); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_383(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 383); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_384(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 384); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_385(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 385); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_386(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 386); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_387(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 387); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_388(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 388); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_389(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 389); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_390(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 390); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_391(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 391); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_392(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 392); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_393(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 393); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_394(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 394); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_395(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 395); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_396(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 396); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_397(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 397); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_398(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 398); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_399(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 399); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_400(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 400); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_401(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 401); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_402(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 402); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_403(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 403); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_404(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 404); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_405(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 405); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_406(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 406); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_407(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 407); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_408(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 408); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_409(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 409); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_410(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 410); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_411(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 411); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_412(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 412); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_413(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 413); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_414(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 414); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_415(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 415); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_416(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 416); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_417(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 417); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_418(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 418); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_419(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 419); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_420(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 420); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_421(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 421); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_422(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 422); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_423(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 423); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_424(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 424); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_425(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 425); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_426(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 426); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_427(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 427); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_428(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 428); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_429(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 429); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_430(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 430); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_431(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 431); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_432(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 432); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_433(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 433); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_434(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 434); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_435(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 435); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_436(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 436); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_437(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 437); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_438(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 438); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_439(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 439); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_440(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 440); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_441(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 441); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_442(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 442); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_443(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 443); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_444(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 444); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_445(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 445); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_446(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 446); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_447(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 447); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_448(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 448); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_449(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 449); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_450(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 450); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_451(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 451); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_452(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 452); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_453(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 453); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_454(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 454); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_455(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 455); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_456(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 456); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_457(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 457); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_458(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 458); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_459(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 459); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_460(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 460); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_461(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 461); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_462(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 462); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_463(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 463); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_464(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 464); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_465(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 465); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_466(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 466); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_467(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 467); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_468(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 468); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_469(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 469); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_470(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 470); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_471(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 471); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_472(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 472); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_473(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 473); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_474(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 474); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_475(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 475); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_476(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 476); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_477(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 477); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_478(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 478); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_479(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 479); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_480(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 480); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_481(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 481); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_482(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 482); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_483(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 483); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_484(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 484); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_485(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 485); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_486(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 486); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_487(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 487); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_488(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 488); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_489(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 489); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_490(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 490); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_491(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 491); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_492(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 492); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_493(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 493); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_494(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 494); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_495(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 495); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_496(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 496); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_497(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 497); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_498(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 498); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_499(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 499); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_500(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 500); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_501(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 501); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_502(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 502); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_503(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 503); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_504(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 504); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_505(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 505); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_506(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 506); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_507(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 507); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_508(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 508); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_509(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 509); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_510(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 510); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_511(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 511); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_512(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 512); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_513(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 513); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_514(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 514); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_515(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 515); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_516(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 516); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_517(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 517); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_518(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 518); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_519(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 519); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_520(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 520); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_521(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 521); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_522(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 522); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_523(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 523); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_524(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 524); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_525(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 525); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_526(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 526); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_527(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 527); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_528(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 528); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_529(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 529); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_530(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 530); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_531(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 531); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_532(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 532); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_533(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 533); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_534(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 534); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_535(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 535); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_536(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 536); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_537(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 537); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_538(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 538); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_539(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 539); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_540(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 540); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_541(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 541); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_542(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 542); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_543(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 543); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_544(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 544); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_545(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 545); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_546(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 546); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_547(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 547); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_548(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 548); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_549(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 549); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_550(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 550); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_551(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 551); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_552(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 552); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_553(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 553); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_554(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 554); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_555(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 555); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_556(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 556); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_557(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 557); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_558(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 558); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_559(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 559); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_560(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 560); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_561(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 561); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_562(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 562); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_563(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 563); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_564(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 564); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_565(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 565); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_566(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 566); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_567(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 567); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_568(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 568); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_569(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 569); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_570(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 570); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_571(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 571); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_572(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 572); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_573(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 573); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_574(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 574); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_575(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 575); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_576(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 576); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_577(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 577); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_578(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 578); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_579(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 579); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_580(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 580); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_581(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 581); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_582(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 582); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_583(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 583); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_584(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 584); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_585(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 585); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_586(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 586); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_587(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 587); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_588(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 588); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_589(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 589); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_590(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 590); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_591(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 591); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_592(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 592); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_593(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 593); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_594(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 594); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_595(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 595); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_596(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 596); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_597(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 597); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_598(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 598); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_599(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 599); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_600(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 600); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_601(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 601); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_602(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 602); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_603(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 603); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_604(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 604); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_605(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 605); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_606(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 606); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_607(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 607); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_608(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 608); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_609(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 609); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_610(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 610); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_611(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 611); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_612(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 612); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_613(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 613); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_614(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 614); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_615(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 615); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_616(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 616); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_617(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 617); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_618(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 618); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_619(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 619); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_620(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 620); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_621(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 621); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_622(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 622); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_623(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 623); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_624(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 624); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_625(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 625); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_626(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 626); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_627(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 627); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_628(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 628); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_629(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 629); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_630(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 630); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_631(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 631); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_632(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 632); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_633(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 633); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_634(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 634); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_635(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 635); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_636(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 636); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_637(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 637); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_638(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 638); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_639(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 639); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_640(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 640); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_641(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 641); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_642(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 642); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_643(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 643); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_644(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 644); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_645(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 645); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_646(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 646); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_647(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 647); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_648(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 648); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_649(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 649); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_650(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 650); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_651(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 651); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_652(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 652); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_653(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 653); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_654(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 654); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_655(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 655); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_656(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 656); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_657(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 657); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_658(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 658); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_659(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 659); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_660(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 660); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_661(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 661); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_662(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 662); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_663(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 663); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_664(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 664); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_665(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 665); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_666(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 666); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_667(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 667); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_668(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 668); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_669(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 669); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_670(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 670); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_671(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 671); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_672(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 672); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_673(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 673); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_674(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 674); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_675(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 675); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_676(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 676); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_677(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 677); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_678(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 678); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_679(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 679); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_680(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 680); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_681(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 681); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_682(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 682); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_683(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 683); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_684(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 684); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_685(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 685); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_686(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 686); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_687(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 687); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_688(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 688); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_689(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 689); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_690(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 690); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_691(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 691); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_692(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 692); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_693(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 693); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_694(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 694); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_695(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 695); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_696(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 696); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_697(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 697); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_698(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 698); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_699(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 699); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_700(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 700); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_701(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 701); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_702(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 702); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_703(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 703); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_704(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 704); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_705(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 705); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_706(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 706); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_707(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 707); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_708(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 708); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_709(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 709); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_710(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 710); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_711(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 711); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_712(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 712); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_713(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 713); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_714(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 714); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_715(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 715); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_716(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 716); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_717(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 717); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_718(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 718); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_719(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 719); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_720(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 720); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_721(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 721); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_722(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 722); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_723(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 723); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_724(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 724); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_725(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 725); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_726(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 726); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_727(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 727); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_728(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 728); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_729(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 729); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_730(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 730); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_731(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 731); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_732(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 732); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_733(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 733); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_734(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 734); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_735(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 735); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_736(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 736); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_737(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 737); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_738(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 738); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_739(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 739); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_740(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 740); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_741(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 741); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_742(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 742); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_743(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 743); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_744(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 744); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_745(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 745); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_746(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 746); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_747(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 747); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_748(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 748); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_749(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 749); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_750(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 750); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_751(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 751); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_752(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 752); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_753(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 753); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_754(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 754); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_755(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 755); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_756(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 756); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_757(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 757); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_758(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 758); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_759(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 759); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_760(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 760); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_761(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 761); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_762(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 762); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_763(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 763); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_764(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 764); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_765(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 765); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_766(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 766); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_767(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 767); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_768(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 768); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_769(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 769); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_770(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 770); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_771(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 771); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_772(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 772); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_773(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 773); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_774(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 774); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_775(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 775); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_776(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 776); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_777(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 777); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_778(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 778); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_779(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 779); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_780(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 780); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_781(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 781); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_782(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 782); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_783(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 783); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_784(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 784); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_785(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 785); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_786(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 786); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_787(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 787); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_788(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 788); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_789(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 789); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_790(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 790); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_791(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 791); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_792(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 792); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_793(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 793); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_794(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 794); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_795(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 795); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_796(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 796); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_797(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 797); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_798(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 798); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_799(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 799); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_800(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 800); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_801(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 801); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_802(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 802); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_803(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 803); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_804(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 804); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_805(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 805); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_806(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 806); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_807(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 807); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_808(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 808); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_809(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 809); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_810(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 810); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_811(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 811); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_812(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 812); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_813(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 813); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_814(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 814); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_815(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 815); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_816(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 816); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_817(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 817); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_818(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 818); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_819(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 819); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_820(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 820); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_821(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 821); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_822(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 822); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_823(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 823); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_824(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 824); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_825(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 825); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_826(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 826); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_827(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 827); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_828(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 828); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_829(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 829); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_830(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 830); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_831(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 831); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_832(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 832); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_833(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 833); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_834(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 834); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_835(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 835); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_836(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 836); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_837(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 837); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_838(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 838); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_839(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 839); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_840(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 840); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_841(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 841); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_842(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 842); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_843(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 843); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_844(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 844); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_845(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 845); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_846(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 846); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_847(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 847); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_848(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 848); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_849(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 849); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_850(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 850); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_851(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 851); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_852(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 852); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_853(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 853); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_854(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 854); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_855(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 855); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_856(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 856); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_857(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 857); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_858(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 858); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_859(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 859); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_860(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 860); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_861(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 861); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_862(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 862); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_863(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 863); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_864(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 864); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_865(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 865); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_866(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 866); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_867(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 867); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_868(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 868); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_869(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 869); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_870(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 870); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_871(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 871); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_872(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 872); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_873(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 873); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_874(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 874); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_875(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 875); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_876(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 876); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_877(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 877); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_878(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 878); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_879(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 879); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_880(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 880); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_881(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 881); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_882(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 882); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_883(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 883); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_884(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 884); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_885(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 885); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_886(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 886); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_887(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 887); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_888(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 888); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_889(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 889); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_890(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 890); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_891(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 891); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_892(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 892); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_893(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 893); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_894(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 894); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_895(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 895); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_896(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 896); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_897(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 897); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_898(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 898); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_899(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 899); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_900(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 900); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_901(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 901); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_902(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 902); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_903(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 903); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_904(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 904); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_905(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 905); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_906(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 906); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_907(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 907); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_908(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 908); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_909(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 909); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_910(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 910); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_911(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 911); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_912(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 912); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_913(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 913); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_914(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 914); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_915(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 915); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_916(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 916); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_917(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 917); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_918(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 918); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_919(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 919); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_920(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 920); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_921(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 921); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_922(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 922); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_923(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 923); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_924(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 924); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_925(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 925); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_926(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 926); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_927(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 927); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_928(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 928); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_929(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 929); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_930(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 930); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_931(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 931); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_932(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 932); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_933(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 933); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_934(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 934); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_935(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 935); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_936(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 936); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_937(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 937); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_938(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 938); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_939(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 939); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_940(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 940); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_941(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 941); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_942(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 942); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_943(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 943); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_944(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 944); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_945(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 945); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_946(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 946); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_947(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 947); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_948(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 948); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_949(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 949); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_950(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 950); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_951(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 951); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_952(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 952); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_953(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 953); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_954(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 954); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_955(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 955); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_956(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 956); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_957(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 957); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_958(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 958); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_959(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 959); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_960(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 960); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_961(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 961); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_962(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 962); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_963(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 963); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_964(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 964); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_965(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 965); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_966(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 966); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_967(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 967); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_968(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 968); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_969(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 969); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_970(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 970); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_971(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 971); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_972(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 972); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_973(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 973); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_974(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 974); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_975(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 975); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_976(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 976); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_977(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 977); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_978(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 978); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_979(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 979); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_980(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 980); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_981(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 981); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_982(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 982); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_983(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 983); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_984(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 984); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_985(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 985); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_986(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 986); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_987(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 987); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_988(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 988); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_989(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 989); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_990(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 990); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_991(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 991); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_992(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 992); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_993(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 993); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_994(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 994); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_995(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 995); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_996(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 996); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_997(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 997); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_998(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 998); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_999(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 999); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1000(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1000); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1001(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1001); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1002(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1002); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1003(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1003); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1004(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1004); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1005(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1005); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1006(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1006); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1007(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1007); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1008(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1008); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1009(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1009); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1010(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1010); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1011(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1011); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1012(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1012); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1013(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1013); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1014(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1014); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1015(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1015); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1016(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1016); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1017(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1017); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1018(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1018); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1019(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1019); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1020(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1020); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1021(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1021); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1022(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1022); +} + +/** + * + */ +static SQInteger sr_kemi_sqlang_exec_func_1023(HSQUIRRELVM J) +{ + return sr_kemi_sqlang_exec_func(J, 1023); +} + +/** + * + */ +static sr_kemi_sqlang_export_t _sr_kemi_sqlang_export_list[] = { + { sr_kemi_sqlang_exec_func_0, NULL}, + { sr_kemi_sqlang_exec_func_1, NULL}, + { sr_kemi_sqlang_exec_func_2, NULL}, + { sr_kemi_sqlang_exec_func_3, NULL}, + { sr_kemi_sqlang_exec_func_4, NULL}, + { sr_kemi_sqlang_exec_func_5, NULL}, + { sr_kemi_sqlang_exec_func_6, NULL}, + { sr_kemi_sqlang_exec_func_7, NULL}, + { sr_kemi_sqlang_exec_func_8, NULL}, + { sr_kemi_sqlang_exec_func_9, NULL}, + { sr_kemi_sqlang_exec_func_10, NULL}, + { sr_kemi_sqlang_exec_func_11, NULL}, + { sr_kemi_sqlang_exec_func_12, NULL}, + { sr_kemi_sqlang_exec_func_13, NULL}, + { sr_kemi_sqlang_exec_func_14, NULL}, + { sr_kemi_sqlang_exec_func_15, NULL}, + { sr_kemi_sqlang_exec_func_16, NULL}, + { sr_kemi_sqlang_exec_func_17, NULL}, + { sr_kemi_sqlang_exec_func_18, NULL}, + { sr_kemi_sqlang_exec_func_19, NULL}, + { sr_kemi_sqlang_exec_func_20, NULL}, + { sr_kemi_sqlang_exec_func_21, NULL}, + { sr_kemi_sqlang_exec_func_22, NULL}, + { sr_kemi_sqlang_exec_func_23, NULL}, + { sr_kemi_sqlang_exec_func_24, NULL}, + { sr_kemi_sqlang_exec_func_25, NULL}, + { sr_kemi_sqlang_exec_func_26, NULL}, + { sr_kemi_sqlang_exec_func_27, NULL}, + { sr_kemi_sqlang_exec_func_28, NULL}, + { sr_kemi_sqlang_exec_func_29, NULL}, + { sr_kemi_sqlang_exec_func_30, NULL}, + { sr_kemi_sqlang_exec_func_31, NULL}, + { sr_kemi_sqlang_exec_func_32, NULL}, + { sr_kemi_sqlang_exec_func_33, NULL}, + { sr_kemi_sqlang_exec_func_34, NULL}, + { sr_kemi_sqlang_exec_func_35, NULL}, + { sr_kemi_sqlang_exec_func_36, NULL}, + { sr_kemi_sqlang_exec_func_37, NULL}, + { sr_kemi_sqlang_exec_func_38, NULL}, + { sr_kemi_sqlang_exec_func_39, NULL}, + { sr_kemi_sqlang_exec_func_40, NULL}, + { sr_kemi_sqlang_exec_func_41, NULL}, + { sr_kemi_sqlang_exec_func_42, NULL}, + { sr_kemi_sqlang_exec_func_43, NULL}, + { sr_kemi_sqlang_exec_func_44, NULL}, + { sr_kemi_sqlang_exec_func_45, NULL}, + { sr_kemi_sqlang_exec_func_46, NULL}, + { sr_kemi_sqlang_exec_func_47, NULL}, + { sr_kemi_sqlang_exec_func_48, NULL}, + { sr_kemi_sqlang_exec_func_49, NULL}, + { sr_kemi_sqlang_exec_func_50, NULL}, + { sr_kemi_sqlang_exec_func_51, NULL}, + { sr_kemi_sqlang_exec_func_52, NULL}, + { sr_kemi_sqlang_exec_func_53, NULL}, + { sr_kemi_sqlang_exec_func_54, NULL}, + { sr_kemi_sqlang_exec_func_55, NULL}, + { sr_kemi_sqlang_exec_func_56, NULL}, + { sr_kemi_sqlang_exec_func_57, NULL}, + { sr_kemi_sqlang_exec_func_58, NULL}, + { sr_kemi_sqlang_exec_func_59, NULL}, + { sr_kemi_sqlang_exec_func_60, NULL}, + { sr_kemi_sqlang_exec_func_61, NULL}, + { sr_kemi_sqlang_exec_func_62, NULL}, + { sr_kemi_sqlang_exec_func_63, NULL}, + { sr_kemi_sqlang_exec_func_64, NULL}, + { sr_kemi_sqlang_exec_func_65, NULL}, + { sr_kemi_sqlang_exec_func_66, NULL}, + { sr_kemi_sqlang_exec_func_67, NULL}, + { sr_kemi_sqlang_exec_func_68, NULL}, + { sr_kemi_sqlang_exec_func_69, NULL}, + { sr_kemi_sqlang_exec_func_70, NULL}, + { sr_kemi_sqlang_exec_func_71, NULL}, + { sr_kemi_sqlang_exec_func_72, NULL}, + { sr_kemi_sqlang_exec_func_73, NULL}, + { sr_kemi_sqlang_exec_func_74, NULL}, + { sr_kemi_sqlang_exec_func_75, NULL}, + { sr_kemi_sqlang_exec_func_76, NULL}, + { sr_kemi_sqlang_exec_func_77, NULL}, + { sr_kemi_sqlang_exec_func_78, NULL}, + { sr_kemi_sqlang_exec_func_79, NULL}, + { sr_kemi_sqlang_exec_func_80, NULL}, + { sr_kemi_sqlang_exec_func_81, NULL}, + { sr_kemi_sqlang_exec_func_82, NULL}, + { sr_kemi_sqlang_exec_func_83, NULL}, + { sr_kemi_sqlang_exec_func_84, NULL}, + { sr_kemi_sqlang_exec_func_85, NULL}, + { sr_kemi_sqlang_exec_func_86, NULL}, + { sr_kemi_sqlang_exec_func_87, NULL}, + { sr_kemi_sqlang_exec_func_88, NULL}, + { sr_kemi_sqlang_exec_func_89, NULL}, + { sr_kemi_sqlang_exec_func_90, NULL}, + { sr_kemi_sqlang_exec_func_91, NULL}, + { sr_kemi_sqlang_exec_func_92, NULL}, + { sr_kemi_sqlang_exec_func_93, NULL}, + { sr_kemi_sqlang_exec_func_94, NULL}, + { sr_kemi_sqlang_exec_func_95, NULL}, + { sr_kemi_sqlang_exec_func_96, NULL}, + { sr_kemi_sqlang_exec_func_97, NULL}, + { sr_kemi_sqlang_exec_func_98, NULL}, + { sr_kemi_sqlang_exec_func_99, NULL}, + { sr_kemi_sqlang_exec_func_100, NULL}, + { sr_kemi_sqlang_exec_func_101, NULL}, + { sr_kemi_sqlang_exec_func_102, NULL}, + { sr_kemi_sqlang_exec_func_103, NULL}, + { sr_kemi_sqlang_exec_func_104, NULL}, + { sr_kemi_sqlang_exec_func_105, NULL}, + { sr_kemi_sqlang_exec_func_106, NULL}, + { sr_kemi_sqlang_exec_func_107, NULL}, + { sr_kemi_sqlang_exec_func_108, NULL}, + { sr_kemi_sqlang_exec_func_109, NULL}, + { sr_kemi_sqlang_exec_func_110, NULL}, + { sr_kemi_sqlang_exec_func_111, NULL}, + { sr_kemi_sqlang_exec_func_112, NULL}, + { sr_kemi_sqlang_exec_func_113, NULL}, + { sr_kemi_sqlang_exec_func_114, NULL}, + { sr_kemi_sqlang_exec_func_115, NULL}, + { sr_kemi_sqlang_exec_func_116, NULL}, + { sr_kemi_sqlang_exec_func_117, NULL}, + { sr_kemi_sqlang_exec_func_118, NULL}, + { sr_kemi_sqlang_exec_func_119, NULL}, + { sr_kemi_sqlang_exec_func_120, NULL}, + { sr_kemi_sqlang_exec_func_121, NULL}, + { sr_kemi_sqlang_exec_func_122, NULL}, + { sr_kemi_sqlang_exec_func_123, NULL}, + { sr_kemi_sqlang_exec_func_124, NULL}, + { sr_kemi_sqlang_exec_func_125, NULL}, + { sr_kemi_sqlang_exec_func_126, NULL}, + { sr_kemi_sqlang_exec_func_127, NULL}, + { sr_kemi_sqlang_exec_func_128, NULL}, + { sr_kemi_sqlang_exec_func_129, NULL}, + { sr_kemi_sqlang_exec_func_130, NULL}, + { sr_kemi_sqlang_exec_func_131, NULL}, + { sr_kemi_sqlang_exec_func_132, NULL}, + { sr_kemi_sqlang_exec_func_133, NULL}, + { sr_kemi_sqlang_exec_func_134, NULL}, + { sr_kemi_sqlang_exec_func_135, NULL}, + { sr_kemi_sqlang_exec_func_136, NULL}, + { sr_kemi_sqlang_exec_func_137, NULL}, + { sr_kemi_sqlang_exec_func_138, NULL}, + { sr_kemi_sqlang_exec_func_139, NULL}, + { sr_kemi_sqlang_exec_func_140, NULL}, + { sr_kemi_sqlang_exec_func_141, NULL}, + { sr_kemi_sqlang_exec_func_142, NULL}, + { sr_kemi_sqlang_exec_func_143, NULL}, + { sr_kemi_sqlang_exec_func_144, NULL}, + { sr_kemi_sqlang_exec_func_145, NULL}, + { sr_kemi_sqlang_exec_func_146, NULL}, + { sr_kemi_sqlang_exec_func_147, NULL}, + { sr_kemi_sqlang_exec_func_148, NULL}, + { sr_kemi_sqlang_exec_func_149, NULL}, + { sr_kemi_sqlang_exec_func_150, NULL}, + { sr_kemi_sqlang_exec_func_151, NULL}, + { sr_kemi_sqlang_exec_func_152, NULL}, + { sr_kemi_sqlang_exec_func_153, NULL}, + { sr_kemi_sqlang_exec_func_154, NULL}, + { sr_kemi_sqlang_exec_func_155, NULL}, + { sr_kemi_sqlang_exec_func_156, NULL}, + { sr_kemi_sqlang_exec_func_157, NULL}, + { sr_kemi_sqlang_exec_func_158, NULL}, + { sr_kemi_sqlang_exec_func_159, NULL}, + { sr_kemi_sqlang_exec_func_160, NULL}, + { sr_kemi_sqlang_exec_func_161, NULL}, + { sr_kemi_sqlang_exec_func_162, NULL}, + { sr_kemi_sqlang_exec_func_163, NULL}, + { sr_kemi_sqlang_exec_func_164, NULL}, + { sr_kemi_sqlang_exec_func_165, NULL}, + { sr_kemi_sqlang_exec_func_166, NULL}, + { sr_kemi_sqlang_exec_func_167, NULL}, + { sr_kemi_sqlang_exec_func_168, NULL}, + { sr_kemi_sqlang_exec_func_169, NULL}, + { sr_kemi_sqlang_exec_func_170, NULL}, + { sr_kemi_sqlang_exec_func_171, NULL}, + { sr_kemi_sqlang_exec_func_172, NULL}, + { sr_kemi_sqlang_exec_func_173, NULL}, + { sr_kemi_sqlang_exec_func_174, NULL}, + { sr_kemi_sqlang_exec_func_175, NULL}, + { sr_kemi_sqlang_exec_func_176, NULL}, + { sr_kemi_sqlang_exec_func_177, NULL}, + { sr_kemi_sqlang_exec_func_178, NULL}, + { sr_kemi_sqlang_exec_func_179, NULL}, + { sr_kemi_sqlang_exec_func_180, NULL}, + { sr_kemi_sqlang_exec_func_181, NULL}, + { sr_kemi_sqlang_exec_func_182, NULL}, + { sr_kemi_sqlang_exec_func_183, NULL}, + { sr_kemi_sqlang_exec_func_184, NULL}, + { sr_kemi_sqlang_exec_func_185, NULL}, + { sr_kemi_sqlang_exec_func_186, NULL}, + { sr_kemi_sqlang_exec_func_187, NULL}, + { sr_kemi_sqlang_exec_func_188, NULL}, + { sr_kemi_sqlang_exec_func_189, NULL}, + { sr_kemi_sqlang_exec_func_190, NULL}, + { sr_kemi_sqlang_exec_func_191, NULL}, + { sr_kemi_sqlang_exec_func_192, NULL}, + { sr_kemi_sqlang_exec_func_193, NULL}, + { sr_kemi_sqlang_exec_func_194, NULL}, + { sr_kemi_sqlang_exec_func_195, NULL}, + { sr_kemi_sqlang_exec_func_196, NULL}, + { sr_kemi_sqlang_exec_func_197, NULL}, + { sr_kemi_sqlang_exec_func_198, NULL}, + { sr_kemi_sqlang_exec_func_199, NULL}, + { sr_kemi_sqlang_exec_func_200, NULL}, + { sr_kemi_sqlang_exec_func_201, NULL}, + { sr_kemi_sqlang_exec_func_202, NULL}, + { sr_kemi_sqlang_exec_func_203, NULL}, + { sr_kemi_sqlang_exec_func_204, NULL}, + { sr_kemi_sqlang_exec_func_205, NULL}, + { sr_kemi_sqlang_exec_func_206, NULL}, + { sr_kemi_sqlang_exec_func_207, NULL}, + { sr_kemi_sqlang_exec_func_208, NULL}, + { sr_kemi_sqlang_exec_func_209, NULL}, + { sr_kemi_sqlang_exec_func_210, NULL}, + { sr_kemi_sqlang_exec_func_211, NULL}, + { sr_kemi_sqlang_exec_func_212, NULL}, + { sr_kemi_sqlang_exec_func_213, NULL}, + { sr_kemi_sqlang_exec_func_214, NULL}, + { sr_kemi_sqlang_exec_func_215, NULL}, + { sr_kemi_sqlang_exec_func_216, NULL}, + { sr_kemi_sqlang_exec_func_217, NULL}, + { sr_kemi_sqlang_exec_func_218, NULL}, + { sr_kemi_sqlang_exec_func_219, NULL}, + { sr_kemi_sqlang_exec_func_220, NULL}, + { sr_kemi_sqlang_exec_func_221, NULL}, + { sr_kemi_sqlang_exec_func_222, NULL}, + { sr_kemi_sqlang_exec_func_223, NULL}, + { sr_kemi_sqlang_exec_func_224, NULL}, + { sr_kemi_sqlang_exec_func_225, NULL}, + { sr_kemi_sqlang_exec_func_226, NULL}, + { sr_kemi_sqlang_exec_func_227, NULL}, + { sr_kemi_sqlang_exec_func_228, NULL}, + { sr_kemi_sqlang_exec_func_229, NULL}, + { sr_kemi_sqlang_exec_func_230, NULL}, + { sr_kemi_sqlang_exec_func_231, NULL}, + { sr_kemi_sqlang_exec_func_232, NULL}, + { sr_kemi_sqlang_exec_func_233, NULL}, + { sr_kemi_sqlang_exec_func_234, NULL}, + { sr_kemi_sqlang_exec_func_235, NULL}, + { sr_kemi_sqlang_exec_func_236, NULL}, + { sr_kemi_sqlang_exec_func_237, NULL}, + { sr_kemi_sqlang_exec_func_238, NULL}, + { sr_kemi_sqlang_exec_func_239, NULL}, + { sr_kemi_sqlang_exec_func_240, NULL}, + { sr_kemi_sqlang_exec_func_241, NULL}, + { sr_kemi_sqlang_exec_func_242, NULL}, + { sr_kemi_sqlang_exec_func_243, NULL}, + { sr_kemi_sqlang_exec_func_244, NULL}, + { sr_kemi_sqlang_exec_func_245, NULL}, + { sr_kemi_sqlang_exec_func_246, NULL}, + { sr_kemi_sqlang_exec_func_247, NULL}, + { sr_kemi_sqlang_exec_func_248, NULL}, + { sr_kemi_sqlang_exec_func_249, NULL}, + { sr_kemi_sqlang_exec_func_250, NULL}, + { sr_kemi_sqlang_exec_func_251, NULL}, + { sr_kemi_sqlang_exec_func_252, NULL}, + { sr_kemi_sqlang_exec_func_253, NULL}, + { sr_kemi_sqlang_exec_func_254, NULL}, + { sr_kemi_sqlang_exec_func_255, NULL}, + { sr_kemi_sqlang_exec_func_256, NULL}, + { sr_kemi_sqlang_exec_func_257, NULL}, + { sr_kemi_sqlang_exec_func_258, NULL}, + { sr_kemi_sqlang_exec_func_259, NULL}, + { sr_kemi_sqlang_exec_func_260, NULL}, + { sr_kemi_sqlang_exec_func_261, NULL}, + { sr_kemi_sqlang_exec_func_262, NULL}, + { sr_kemi_sqlang_exec_func_263, NULL}, + { sr_kemi_sqlang_exec_func_264, NULL}, + { sr_kemi_sqlang_exec_func_265, NULL}, + { sr_kemi_sqlang_exec_func_266, NULL}, + { sr_kemi_sqlang_exec_func_267, NULL}, + { sr_kemi_sqlang_exec_func_268, NULL}, + { sr_kemi_sqlang_exec_func_269, NULL}, + { sr_kemi_sqlang_exec_func_270, NULL}, + { sr_kemi_sqlang_exec_func_271, NULL}, + { sr_kemi_sqlang_exec_func_272, NULL}, + { sr_kemi_sqlang_exec_func_273, NULL}, + { sr_kemi_sqlang_exec_func_274, NULL}, + { sr_kemi_sqlang_exec_func_275, NULL}, + { sr_kemi_sqlang_exec_func_276, NULL}, + { sr_kemi_sqlang_exec_func_277, NULL}, + { sr_kemi_sqlang_exec_func_278, NULL}, + { sr_kemi_sqlang_exec_func_279, NULL}, + { sr_kemi_sqlang_exec_func_280, NULL}, + { sr_kemi_sqlang_exec_func_281, NULL}, + { sr_kemi_sqlang_exec_func_282, NULL}, + { sr_kemi_sqlang_exec_func_283, NULL}, + { sr_kemi_sqlang_exec_func_284, NULL}, + { sr_kemi_sqlang_exec_func_285, NULL}, + { sr_kemi_sqlang_exec_func_286, NULL}, + { sr_kemi_sqlang_exec_func_287, NULL}, + { sr_kemi_sqlang_exec_func_288, NULL}, + { sr_kemi_sqlang_exec_func_289, NULL}, + { sr_kemi_sqlang_exec_func_290, NULL}, + { sr_kemi_sqlang_exec_func_291, NULL}, + { sr_kemi_sqlang_exec_func_292, NULL}, + { sr_kemi_sqlang_exec_func_293, NULL}, + { sr_kemi_sqlang_exec_func_294, NULL}, + { sr_kemi_sqlang_exec_func_295, NULL}, + { sr_kemi_sqlang_exec_func_296, NULL}, + { sr_kemi_sqlang_exec_func_297, NULL}, + { sr_kemi_sqlang_exec_func_298, NULL}, + { sr_kemi_sqlang_exec_func_299, NULL}, + { sr_kemi_sqlang_exec_func_300, NULL}, + { sr_kemi_sqlang_exec_func_301, NULL}, + { sr_kemi_sqlang_exec_func_302, NULL}, + { sr_kemi_sqlang_exec_func_303, NULL}, + { sr_kemi_sqlang_exec_func_304, NULL}, + { sr_kemi_sqlang_exec_func_305, NULL}, + { sr_kemi_sqlang_exec_func_306, NULL}, + { sr_kemi_sqlang_exec_func_307, NULL}, + { sr_kemi_sqlang_exec_func_308, NULL}, + { sr_kemi_sqlang_exec_func_309, NULL}, + { sr_kemi_sqlang_exec_func_310, NULL}, + { sr_kemi_sqlang_exec_func_311, NULL}, + { sr_kemi_sqlang_exec_func_312, NULL}, + { sr_kemi_sqlang_exec_func_313, NULL}, + { sr_kemi_sqlang_exec_func_314, NULL}, + { sr_kemi_sqlang_exec_func_315, NULL}, + { sr_kemi_sqlang_exec_func_316, NULL}, + { sr_kemi_sqlang_exec_func_317, NULL}, + { sr_kemi_sqlang_exec_func_318, NULL}, + { sr_kemi_sqlang_exec_func_319, NULL}, + { sr_kemi_sqlang_exec_func_320, NULL}, + { sr_kemi_sqlang_exec_func_321, NULL}, + { sr_kemi_sqlang_exec_func_322, NULL}, + { sr_kemi_sqlang_exec_func_323, NULL}, + { sr_kemi_sqlang_exec_func_324, NULL}, + { sr_kemi_sqlang_exec_func_325, NULL}, + { sr_kemi_sqlang_exec_func_326, NULL}, + { sr_kemi_sqlang_exec_func_327, NULL}, + { sr_kemi_sqlang_exec_func_328, NULL}, + { sr_kemi_sqlang_exec_func_329, NULL}, + { sr_kemi_sqlang_exec_func_330, NULL}, + { sr_kemi_sqlang_exec_func_331, NULL}, + { sr_kemi_sqlang_exec_func_332, NULL}, + { sr_kemi_sqlang_exec_func_333, NULL}, + { sr_kemi_sqlang_exec_func_334, NULL}, + { sr_kemi_sqlang_exec_func_335, NULL}, + { sr_kemi_sqlang_exec_func_336, NULL}, + { sr_kemi_sqlang_exec_func_337, NULL}, + { sr_kemi_sqlang_exec_func_338, NULL}, + { sr_kemi_sqlang_exec_func_339, NULL}, + { sr_kemi_sqlang_exec_func_340, NULL}, + { sr_kemi_sqlang_exec_func_341, NULL}, + { sr_kemi_sqlang_exec_func_342, NULL}, + { sr_kemi_sqlang_exec_func_343, NULL}, + { sr_kemi_sqlang_exec_func_344, NULL}, + { sr_kemi_sqlang_exec_func_345, NULL}, + { sr_kemi_sqlang_exec_func_346, NULL}, + { sr_kemi_sqlang_exec_func_347, NULL}, + { sr_kemi_sqlang_exec_func_348, NULL}, + { sr_kemi_sqlang_exec_func_349, NULL}, + { sr_kemi_sqlang_exec_func_350, NULL}, + { sr_kemi_sqlang_exec_func_351, NULL}, + { sr_kemi_sqlang_exec_func_352, NULL}, + { sr_kemi_sqlang_exec_func_353, NULL}, + { sr_kemi_sqlang_exec_func_354, NULL}, + { sr_kemi_sqlang_exec_func_355, NULL}, + { sr_kemi_sqlang_exec_func_356, NULL}, + { sr_kemi_sqlang_exec_func_357, NULL}, + { sr_kemi_sqlang_exec_func_358, NULL}, + { sr_kemi_sqlang_exec_func_359, NULL}, + { sr_kemi_sqlang_exec_func_360, NULL}, + { sr_kemi_sqlang_exec_func_361, NULL}, + { sr_kemi_sqlang_exec_func_362, NULL}, + { sr_kemi_sqlang_exec_func_363, NULL}, + { sr_kemi_sqlang_exec_func_364, NULL}, + { sr_kemi_sqlang_exec_func_365, NULL}, + { sr_kemi_sqlang_exec_func_366, NULL}, + { sr_kemi_sqlang_exec_func_367, NULL}, + { sr_kemi_sqlang_exec_func_368, NULL}, + { sr_kemi_sqlang_exec_func_369, NULL}, + { sr_kemi_sqlang_exec_func_370, NULL}, + { sr_kemi_sqlang_exec_func_371, NULL}, + { sr_kemi_sqlang_exec_func_372, NULL}, + { sr_kemi_sqlang_exec_func_373, NULL}, + { sr_kemi_sqlang_exec_func_374, NULL}, + { sr_kemi_sqlang_exec_func_375, NULL}, + { sr_kemi_sqlang_exec_func_376, NULL}, + { sr_kemi_sqlang_exec_func_377, NULL}, + { sr_kemi_sqlang_exec_func_378, NULL}, + { sr_kemi_sqlang_exec_func_379, NULL}, + { sr_kemi_sqlang_exec_func_380, NULL}, + { sr_kemi_sqlang_exec_func_381, NULL}, + { sr_kemi_sqlang_exec_func_382, NULL}, + { sr_kemi_sqlang_exec_func_383, NULL}, + { sr_kemi_sqlang_exec_func_384, NULL}, + { sr_kemi_sqlang_exec_func_385, NULL}, + { sr_kemi_sqlang_exec_func_386, NULL}, + { sr_kemi_sqlang_exec_func_387, NULL}, + { sr_kemi_sqlang_exec_func_388, NULL}, + { sr_kemi_sqlang_exec_func_389, NULL}, + { sr_kemi_sqlang_exec_func_390, NULL}, + { sr_kemi_sqlang_exec_func_391, NULL}, + { sr_kemi_sqlang_exec_func_392, NULL}, + { sr_kemi_sqlang_exec_func_393, NULL}, + { sr_kemi_sqlang_exec_func_394, NULL}, + { sr_kemi_sqlang_exec_func_395, NULL}, + { sr_kemi_sqlang_exec_func_396, NULL}, + { sr_kemi_sqlang_exec_func_397, NULL}, + { sr_kemi_sqlang_exec_func_398, NULL}, + { sr_kemi_sqlang_exec_func_399, NULL}, + { sr_kemi_sqlang_exec_func_400, NULL}, + { sr_kemi_sqlang_exec_func_401, NULL}, + { sr_kemi_sqlang_exec_func_402, NULL}, + { sr_kemi_sqlang_exec_func_403, NULL}, + { sr_kemi_sqlang_exec_func_404, NULL}, + { sr_kemi_sqlang_exec_func_405, NULL}, + { sr_kemi_sqlang_exec_func_406, NULL}, + { sr_kemi_sqlang_exec_func_407, NULL}, + { sr_kemi_sqlang_exec_func_408, NULL}, + { sr_kemi_sqlang_exec_func_409, NULL}, + { sr_kemi_sqlang_exec_func_410, NULL}, + { sr_kemi_sqlang_exec_func_411, NULL}, + { sr_kemi_sqlang_exec_func_412, NULL}, + { sr_kemi_sqlang_exec_func_413, NULL}, + { sr_kemi_sqlang_exec_func_414, NULL}, + { sr_kemi_sqlang_exec_func_415, NULL}, + { sr_kemi_sqlang_exec_func_416, NULL}, + { sr_kemi_sqlang_exec_func_417, NULL}, + { sr_kemi_sqlang_exec_func_418, NULL}, + { sr_kemi_sqlang_exec_func_419, NULL}, + { sr_kemi_sqlang_exec_func_420, NULL}, + { sr_kemi_sqlang_exec_func_421, NULL}, + { sr_kemi_sqlang_exec_func_422, NULL}, + { sr_kemi_sqlang_exec_func_423, NULL}, + { sr_kemi_sqlang_exec_func_424, NULL}, + { sr_kemi_sqlang_exec_func_425, NULL}, + { sr_kemi_sqlang_exec_func_426, NULL}, + { sr_kemi_sqlang_exec_func_427, NULL}, + { sr_kemi_sqlang_exec_func_428, NULL}, + { sr_kemi_sqlang_exec_func_429, NULL}, + { sr_kemi_sqlang_exec_func_430, NULL}, + { sr_kemi_sqlang_exec_func_431, NULL}, + { sr_kemi_sqlang_exec_func_432, NULL}, + { sr_kemi_sqlang_exec_func_433, NULL}, + { sr_kemi_sqlang_exec_func_434, NULL}, + { sr_kemi_sqlang_exec_func_435, NULL}, + { sr_kemi_sqlang_exec_func_436, NULL}, + { sr_kemi_sqlang_exec_func_437, NULL}, + { sr_kemi_sqlang_exec_func_438, NULL}, + { sr_kemi_sqlang_exec_func_439, NULL}, + { sr_kemi_sqlang_exec_func_440, NULL}, + { sr_kemi_sqlang_exec_func_441, NULL}, + { sr_kemi_sqlang_exec_func_442, NULL}, + { sr_kemi_sqlang_exec_func_443, NULL}, + { sr_kemi_sqlang_exec_func_444, NULL}, + { sr_kemi_sqlang_exec_func_445, NULL}, + { sr_kemi_sqlang_exec_func_446, NULL}, + { sr_kemi_sqlang_exec_func_447, NULL}, + { sr_kemi_sqlang_exec_func_448, NULL}, + { sr_kemi_sqlang_exec_func_449, NULL}, + { sr_kemi_sqlang_exec_func_450, NULL}, + { sr_kemi_sqlang_exec_func_451, NULL}, + { sr_kemi_sqlang_exec_func_452, NULL}, + { sr_kemi_sqlang_exec_func_453, NULL}, + { sr_kemi_sqlang_exec_func_454, NULL}, + { sr_kemi_sqlang_exec_func_455, NULL}, + { sr_kemi_sqlang_exec_func_456, NULL}, + { sr_kemi_sqlang_exec_func_457, NULL}, + { sr_kemi_sqlang_exec_func_458, NULL}, + { sr_kemi_sqlang_exec_func_459, NULL}, + { sr_kemi_sqlang_exec_func_460, NULL}, + { sr_kemi_sqlang_exec_func_461, NULL}, + { sr_kemi_sqlang_exec_func_462, NULL}, + { sr_kemi_sqlang_exec_func_463, NULL}, + { sr_kemi_sqlang_exec_func_464, NULL}, + { sr_kemi_sqlang_exec_func_465, NULL}, + { sr_kemi_sqlang_exec_func_466, NULL}, + { sr_kemi_sqlang_exec_func_467, NULL}, + { sr_kemi_sqlang_exec_func_468, NULL}, + { sr_kemi_sqlang_exec_func_469, NULL}, + { sr_kemi_sqlang_exec_func_470, NULL}, + { sr_kemi_sqlang_exec_func_471, NULL}, + { sr_kemi_sqlang_exec_func_472, NULL}, + { sr_kemi_sqlang_exec_func_473, NULL}, + { sr_kemi_sqlang_exec_func_474, NULL}, + { sr_kemi_sqlang_exec_func_475, NULL}, + { sr_kemi_sqlang_exec_func_476, NULL}, + { sr_kemi_sqlang_exec_func_477, NULL}, + { sr_kemi_sqlang_exec_func_478, NULL}, + { sr_kemi_sqlang_exec_func_479, NULL}, + { sr_kemi_sqlang_exec_func_480, NULL}, + { sr_kemi_sqlang_exec_func_481, NULL}, + { sr_kemi_sqlang_exec_func_482, NULL}, + { sr_kemi_sqlang_exec_func_483, NULL}, + { sr_kemi_sqlang_exec_func_484, NULL}, + { sr_kemi_sqlang_exec_func_485, NULL}, + { sr_kemi_sqlang_exec_func_486, NULL}, + { sr_kemi_sqlang_exec_func_487, NULL}, + { sr_kemi_sqlang_exec_func_488, NULL}, + { sr_kemi_sqlang_exec_func_489, NULL}, + { sr_kemi_sqlang_exec_func_490, NULL}, + { sr_kemi_sqlang_exec_func_491, NULL}, + { sr_kemi_sqlang_exec_func_492, NULL}, + { sr_kemi_sqlang_exec_func_493, NULL}, + { sr_kemi_sqlang_exec_func_494, NULL}, + { sr_kemi_sqlang_exec_func_495, NULL}, + { sr_kemi_sqlang_exec_func_496, NULL}, + { sr_kemi_sqlang_exec_func_497, NULL}, + { sr_kemi_sqlang_exec_func_498, NULL}, + { sr_kemi_sqlang_exec_func_499, NULL}, + { sr_kemi_sqlang_exec_func_500, NULL}, + { sr_kemi_sqlang_exec_func_501, NULL}, + { sr_kemi_sqlang_exec_func_502, NULL}, + { sr_kemi_sqlang_exec_func_503, NULL}, + { sr_kemi_sqlang_exec_func_504, NULL}, + { sr_kemi_sqlang_exec_func_505, NULL}, + { sr_kemi_sqlang_exec_func_506, NULL}, + { sr_kemi_sqlang_exec_func_507, NULL}, + { sr_kemi_sqlang_exec_func_508, NULL}, + { sr_kemi_sqlang_exec_func_509, NULL}, + { sr_kemi_sqlang_exec_func_510, NULL}, + { sr_kemi_sqlang_exec_func_511, NULL}, + { sr_kemi_sqlang_exec_func_512, NULL}, + { sr_kemi_sqlang_exec_func_513, NULL}, + { sr_kemi_sqlang_exec_func_514, NULL}, + { sr_kemi_sqlang_exec_func_515, NULL}, + { sr_kemi_sqlang_exec_func_516, NULL}, + { sr_kemi_sqlang_exec_func_517, NULL}, + { sr_kemi_sqlang_exec_func_518, NULL}, + { sr_kemi_sqlang_exec_func_519, NULL}, + { sr_kemi_sqlang_exec_func_520, NULL}, + { sr_kemi_sqlang_exec_func_521, NULL}, + { sr_kemi_sqlang_exec_func_522, NULL}, + { sr_kemi_sqlang_exec_func_523, NULL}, + { sr_kemi_sqlang_exec_func_524, NULL}, + { sr_kemi_sqlang_exec_func_525, NULL}, + { sr_kemi_sqlang_exec_func_526, NULL}, + { sr_kemi_sqlang_exec_func_527, NULL}, + { sr_kemi_sqlang_exec_func_528, NULL}, + { sr_kemi_sqlang_exec_func_529, NULL}, + { sr_kemi_sqlang_exec_func_530, NULL}, + { sr_kemi_sqlang_exec_func_531, NULL}, + { sr_kemi_sqlang_exec_func_532, NULL}, + { sr_kemi_sqlang_exec_func_533, NULL}, + { sr_kemi_sqlang_exec_func_534, NULL}, + { sr_kemi_sqlang_exec_func_535, NULL}, + { sr_kemi_sqlang_exec_func_536, NULL}, + { sr_kemi_sqlang_exec_func_537, NULL}, + { sr_kemi_sqlang_exec_func_538, NULL}, + { sr_kemi_sqlang_exec_func_539, NULL}, + { sr_kemi_sqlang_exec_func_540, NULL}, + { sr_kemi_sqlang_exec_func_541, NULL}, + { sr_kemi_sqlang_exec_func_542, NULL}, + { sr_kemi_sqlang_exec_func_543, NULL}, + { sr_kemi_sqlang_exec_func_544, NULL}, + { sr_kemi_sqlang_exec_func_545, NULL}, + { sr_kemi_sqlang_exec_func_546, NULL}, + { sr_kemi_sqlang_exec_func_547, NULL}, + { sr_kemi_sqlang_exec_func_548, NULL}, + { sr_kemi_sqlang_exec_func_549, NULL}, + { sr_kemi_sqlang_exec_func_550, NULL}, + { sr_kemi_sqlang_exec_func_551, NULL}, + { sr_kemi_sqlang_exec_func_552, NULL}, + { sr_kemi_sqlang_exec_func_553, NULL}, + { sr_kemi_sqlang_exec_func_554, NULL}, + { sr_kemi_sqlang_exec_func_555, NULL}, + { sr_kemi_sqlang_exec_func_556, NULL}, + { sr_kemi_sqlang_exec_func_557, NULL}, + { sr_kemi_sqlang_exec_func_558, NULL}, + { sr_kemi_sqlang_exec_func_559, NULL}, + { sr_kemi_sqlang_exec_func_560, NULL}, + { sr_kemi_sqlang_exec_func_561, NULL}, + { sr_kemi_sqlang_exec_func_562, NULL}, + { sr_kemi_sqlang_exec_func_563, NULL}, + { sr_kemi_sqlang_exec_func_564, NULL}, + { sr_kemi_sqlang_exec_func_565, NULL}, + { sr_kemi_sqlang_exec_func_566, NULL}, + { sr_kemi_sqlang_exec_func_567, NULL}, + { sr_kemi_sqlang_exec_func_568, NULL}, + { sr_kemi_sqlang_exec_func_569, NULL}, + { sr_kemi_sqlang_exec_func_570, NULL}, + { sr_kemi_sqlang_exec_func_571, NULL}, + { sr_kemi_sqlang_exec_func_572, NULL}, + { sr_kemi_sqlang_exec_func_573, NULL}, + { sr_kemi_sqlang_exec_func_574, NULL}, + { sr_kemi_sqlang_exec_func_575, NULL}, + { sr_kemi_sqlang_exec_func_576, NULL}, + { sr_kemi_sqlang_exec_func_577, NULL}, + { sr_kemi_sqlang_exec_func_578, NULL}, + { sr_kemi_sqlang_exec_func_579, NULL}, + { sr_kemi_sqlang_exec_func_580, NULL}, + { sr_kemi_sqlang_exec_func_581, NULL}, + { sr_kemi_sqlang_exec_func_582, NULL}, + { sr_kemi_sqlang_exec_func_583, NULL}, + { sr_kemi_sqlang_exec_func_584, NULL}, + { sr_kemi_sqlang_exec_func_585, NULL}, + { sr_kemi_sqlang_exec_func_586, NULL}, + { sr_kemi_sqlang_exec_func_587, NULL}, + { sr_kemi_sqlang_exec_func_588, NULL}, + { sr_kemi_sqlang_exec_func_589, NULL}, + { sr_kemi_sqlang_exec_func_590, NULL}, + { sr_kemi_sqlang_exec_func_591, NULL}, + { sr_kemi_sqlang_exec_func_592, NULL}, + { sr_kemi_sqlang_exec_func_593, NULL}, + { sr_kemi_sqlang_exec_func_594, NULL}, + { sr_kemi_sqlang_exec_func_595, NULL}, + { sr_kemi_sqlang_exec_func_596, NULL}, + { sr_kemi_sqlang_exec_func_597, NULL}, + { sr_kemi_sqlang_exec_func_598, NULL}, + { sr_kemi_sqlang_exec_func_599, NULL}, + { sr_kemi_sqlang_exec_func_600, NULL}, + { sr_kemi_sqlang_exec_func_601, NULL}, + { sr_kemi_sqlang_exec_func_602, NULL}, + { sr_kemi_sqlang_exec_func_603, NULL}, + { sr_kemi_sqlang_exec_func_604, NULL}, + { sr_kemi_sqlang_exec_func_605, NULL}, + { sr_kemi_sqlang_exec_func_606, NULL}, + { sr_kemi_sqlang_exec_func_607, NULL}, + { sr_kemi_sqlang_exec_func_608, NULL}, + { sr_kemi_sqlang_exec_func_609, NULL}, + { sr_kemi_sqlang_exec_func_610, NULL}, + { sr_kemi_sqlang_exec_func_611, NULL}, + { sr_kemi_sqlang_exec_func_612, NULL}, + { sr_kemi_sqlang_exec_func_613, NULL}, + { sr_kemi_sqlang_exec_func_614, NULL}, + { sr_kemi_sqlang_exec_func_615, NULL}, + { sr_kemi_sqlang_exec_func_616, NULL}, + { sr_kemi_sqlang_exec_func_617, NULL}, + { sr_kemi_sqlang_exec_func_618, NULL}, + { sr_kemi_sqlang_exec_func_619, NULL}, + { sr_kemi_sqlang_exec_func_620, NULL}, + { sr_kemi_sqlang_exec_func_621, NULL}, + { sr_kemi_sqlang_exec_func_622, NULL}, + { sr_kemi_sqlang_exec_func_623, NULL}, + { sr_kemi_sqlang_exec_func_624, NULL}, + { sr_kemi_sqlang_exec_func_625, NULL}, + { sr_kemi_sqlang_exec_func_626, NULL}, + { sr_kemi_sqlang_exec_func_627, NULL}, + { sr_kemi_sqlang_exec_func_628, NULL}, + { sr_kemi_sqlang_exec_func_629, NULL}, + { sr_kemi_sqlang_exec_func_630, NULL}, + { sr_kemi_sqlang_exec_func_631, NULL}, + { sr_kemi_sqlang_exec_func_632, NULL}, + { sr_kemi_sqlang_exec_func_633, NULL}, + { sr_kemi_sqlang_exec_func_634, NULL}, + { sr_kemi_sqlang_exec_func_635, NULL}, + { sr_kemi_sqlang_exec_func_636, NULL}, + { sr_kemi_sqlang_exec_func_637, NULL}, + { sr_kemi_sqlang_exec_func_638, NULL}, + { sr_kemi_sqlang_exec_func_639, NULL}, + { sr_kemi_sqlang_exec_func_640, NULL}, + { sr_kemi_sqlang_exec_func_641, NULL}, + { sr_kemi_sqlang_exec_func_642, NULL}, + { sr_kemi_sqlang_exec_func_643, NULL}, + { sr_kemi_sqlang_exec_func_644, NULL}, + { sr_kemi_sqlang_exec_func_645, NULL}, + { sr_kemi_sqlang_exec_func_646, NULL}, + { sr_kemi_sqlang_exec_func_647, NULL}, + { sr_kemi_sqlang_exec_func_648, NULL}, + { sr_kemi_sqlang_exec_func_649, NULL}, + { sr_kemi_sqlang_exec_func_650, NULL}, + { sr_kemi_sqlang_exec_func_651, NULL}, + { sr_kemi_sqlang_exec_func_652, NULL}, + { sr_kemi_sqlang_exec_func_653, NULL}, + { sr_kemi_sqlang_exec_func_654, NULL}, + { sr_kemi_sqlang_exec_func_655, NULL}, + { sr_kemi_sqlang_exec_func_656, NULL}, + { sr_kemi_sqlang_exec_func_657, NULL}, + { sr_kemi_sqlang_exec_func_658, NULL}, + { sr_kemi_sqlang_exec_func_659, NULL}, + { sr_kemi_sqlang_exec_func_660, NULL}, + { sr_kemi_sqlang_exec_func_661, NULL}, + { sr_kemi_sqlang_exec_func_662, NULL}, + { sr_kemi_sqlang_exec_func_663, NULL}, + { sr_kemi_sqlang_exec_func_664, NULL}, + { sr_kemi_sqlang_exec_func_665, NULL}, + { sr_kemi_sqlang_exec_func_666, NULL}, + { sr_kemi_sqlang_exec_func_667, NULL}, + { sr_kemi_sqlang_exec_func_668, NULL}, + { sr_kemi_sqlang_exec_func_669, NULL}, + { sr_kemi_sqlang_exec_func_670, NULL}, + { sr_kemi_sqlang_exec_func_671, NULL}, + { sr_kemi_sqlang_exec_func_672, NULL}, + { sr_kemi_sqlang_exec_func_673, NULL}, + { sr_kemi_sqlang_exec_func_674, NULL}, + { sr_kemi_sqlang_exec_func_675, NULL}, + { sr_kemi_sqlang_exec_func_676, NULL}, + { sr_kemi_sqlang_exec_func_677, NULL}, + { sr_kemi_sqlang_exec_func_678, NULL}, + { sr_kemi_sqlang_exec_func_679, NULL}, + { sr_kemi_sqlang_exec_func_680, NULL}, + { sr_kemi_sqlang_exec_func_681, NULL}, + { sr_kemi_sqlang_exec_func_682, NULL}, + { sr_kemi_sqlang_exec_func_683, NULL}, + { sr_kemi_sqlang_exec_func_684, NULL}, + { sr_kemi_sqlang_exec_func_685, NULL}, + { sr_kemi_sqlang_exec_func_686, NULL}, + { sr_kemi_sqlang_exec_func_687, NULL}, + { sr_kemi_sqlang_exec_func_688, NULL}, + { sr_kemi_sqlang_exec_func_689, NULL}, + { sr_kemi_sqlang_exec_func_690, NULL}, + { sr_kemi_sqlang_exec_func_691, NULL}, + { sr_kemi_sqlang_exec_func_692, NULL}, + { sr_kemi_sqlang_exec_func_693, NULL}, + { sr_kemi_sqlang_exec_func_694, NULL}, + { sr_kemi_sqlang_exec_func_695, NULL}, + { sr_kemi_sqlang_exec_func_696, NULL}, + { sr_kemi_sqlang_exec_func_697, NULL}, + { sr_kemi_sqlang_exec_func_698, NULL}, + { sr_kemi_sqlang_exec_func_699, NULL}, + { sr_kemi_sqlang_exec_func_700, NULL}, + { sr_kemi_sqlang_exec_func_701, NULL}, + { sr_kemi_sqlang_exec_func_702, NULL}, + { sr_kemi_sqlang_exec_func_703, NULL}, + { sr_kemi_sqlang_exec_func_704, NULL}, + { sr_kemi_sqlang_exec_func_705, NULL}, + { sr_kemi_sqlang_exec_func_706, NULL}, + { sr_kemi_sqlang_exec_func_707, NULL}, + { sr_kemi_sqlang_exec_func_708, NULL}, + { sr_kemi_sqlang_exec_func_709, NULL}, + { sr_kemi_sqlang_exec_func_710, NULL}, + { sr_kemi_sqlang_exec_func_711, NULL}, + { sr_kemi_sqlang_exec_func_712, NULL}, + { sr_kemi_sqlang_exec_func_713, NULL}, + { sr_kemi_sqlang_exec_func_714, NULL}, + { sr_kemi_sqlang_exec_func_715, NULL}, + { sr_kemi_sqlang_exec_func_716, NULL}, + { sr_kemi_sqlang_exec_func_717, NULL}, + { sr_kemi_sqlang_exec_func_718, NULL}, + { sr_kemi_sqlang_exec_func_719, NULL}, + { sr_kemi_sqlang_exec_func_720, NULL}, + { sr_kemi_sqlang_exec_func_721, NULL}, + { sr_kemi_sqlang_exec_func_722, NULL}, + { sr_kemi_sqlang_exec_func_723, NULL}, + { sr_kemi_sqlang_exec_func_724, NULL}, + { sr_kemi_sqlang_exec_func_725, NULL}, + { sr_kemi_sqlang_exec_func_726, NULL}, + { sr_kemi_sqlang_exec_func_727, NULL}, + { sr_kemi_sqlang_exec_func_728, NULL}, + { sr_kemi_sqlang_exec_func_729, NULL}, + { sr_kemi_sqlang_exec_func_730, NULL}, + { sr_kemi_sqlang_exec_func_731, NULL}, + { sr_kemi_sqlang_exec_func_732, NULL}, + { sr_kemi_sqlang_exec_func_733, NULL}, + { sr_kemi_sqlang_exec_func_734, NULL}, + { sr_kemi_sqlang_exec_func_735, NULL}, + { sr_kemi_sqlang_exec_func_736, NULL}, + { sr_kemi_sqlang_exec_func_737, NULL}, + { sr_kemi_sqlang_exec_func_738, NULL}, + { sr_kemi_sqlang_exec_func_739, NULL}, + { sr_kemi_sqlang_exec_func_740, NULL}, + { sr_kemi_sqlang_exec_func_741, NULL}, + { sr_kemi_sqlang_exec_func_742, NULL}, + { sr_kemi_sqlang_exec_func_743, NULL}, + { sr_kemi_sqlang_exec_func_744, NULL}, + { sr_kemi_sqlang_exec_func_745, NULL}, + { sr_kemi_sqlang_exec_func_746, NULL}, + { sr_kemi_sqlang_exec_func_747, NULL}, + { sr_kemi_sqlang_exec_func_748, NULL}, + { sr_kemi_sqlang_exec_func_749, NULL}, + { sr_kemi_sqlang_exec_func_750, NULL}, + { sr_kemi_sqlang_exec_func_751, NULL}, + { sr_kemi_sqlang_exec_func_752, NULL}, + { sr_kemi_sqlang_exec_func_753, NULL}, + { sr_kemi_sqlang_exec_func_754, NULL}, + { sr_kemi_sqlang_exec_func_755, NULL}, + { sr_kemi_sqlang_exec_func_756, NULL}, + { sr_kemi_sqlang_exec_func_757, NULL}, + { sr_kemi_sqlang_exec_func_758, NULL}, + { sr_kemi_sqlang_exec_func_759, NULL}, + { sr_kemi_sqlang_exec_func_760, NULL}, + { sr_kemi_sqlang_exec_func_761, NULL}, + { sr_kemi_sqlang_exec_func_762, NULL}, + { sr_kemi_sqlang_exec_func_763, NULL}, + { sr_kemi_sqlang_exec_func_764, NULL}, + { sr_kemi_sqlang_exec_func_765, NULL}, + { sr_kemi_sqlang_exec_func_766, NULL}, + { sr_kemi_sqlang_exec_func_767, NULL}, + { sr_kemi_sqlang_exec_func_768, NULL}, + { sr_kemi_sqlang_exec_func_769, NULL}, + { sr_kemi_sqlang_exec_func_770, NULL}, + { sr_kemi_sqlang_exec_func_771, NULL}, + { sr_kemi_sqlang_exec_func_772, NULL}, + { sr_kemi_sqlang_exec_func_773, NULL}, + { sr_kemi_sqlang_exec_func_774, NULL}, + { sr_kemi_sqlang_exec_func_775, NULL}, + { sr_kemi_sqlang_exec_func_776, NULL}, + { sr_kemi_sqlang_exec_func_777, NULL}, + { sr_kemi_sqlang_exec_func_778, NULL}, + { sr_kemi_sqlang_exec_func_779, NULL}, + { sr_kemi_sqlang_exec_func_780, NULL}, + { sr_kemi_sqlang_exec_func_781, NULL}, + { sr_kemi_sqlang_exec_func_782, NULL}, + { sr_kemi_sqlang_exec_func_783, NULL}, + { sr_kemi_sqlang_exec_func_784, NULL}, + { sr_kemi_sqlang_exec_func_785, NULL}, + { sr_kemi_sqlang_exec_func_786, NULL}, + { sr_kemi_sqlang_exec_func_787, NULL}, + { sr_kemi_sqlang_exec_func_788, NULL}, + { sr_kemi_sqlang_exec_func_789, NULL}, + { sr_kemi_sqlang_exec_func_790, NULL}, + { sr_kemi_sqlang_exec_func_791, NULL}, + { sr_kemi_sqlang_exec_func_792, NULL}, + { sr_kemi_sqlang_exec_func_793, NULL}, + { sr_kemi_sqlang_exec_func_794, NULL}, + { sr_kemi_sqlang_exec_func_795, NULL}, + { sr_kemi_sqlang_exec_func_796, NULL}, + { sr_kemi_sqlang_exec_func_797, NULL}, + { sr_kemi_sqlang_exec_func_798, NULL}, + { sr_kemi_sqlang_exec_func_799, NULL}, + { sr_kemi_sqlang_exec_func_800, NULL}, + { sr_kemi_sqlang_exec_func_801, NULL}, + { sr_kemi_sqlang_exec_func_802, NULL}, + { sr_kemi_sqlang_exec_func_803, NULL}, + { sr_kemi_sqlang_exec_func_804, NULL}, + { sr_kemi_sqlang_exec_func_805, NULL}, + { sr_kemi_sqlang_exec_func_806, NULL}, + { sr_kemi_sqlang_exec_func_807, NULL}, + { sr_kemi_sqlang_exec_func_808, NULL}, + { sr_kemi_sqlang_exec_func_809, NULL}, + { sr_kemi_sqlang_exec_func_810, NULL}, + { sr_kemi_sqlang_exec_func_811, NULL}, + { sr_kemi_sqlang_exec_func_812, NULL}, + { sr_kemi_sqlang_exec_func_813, NULL}, + { sr_kemi_sqlang_exec_func_814, NULL}, + { sr_kemi_sqlang_exec_func_815, NULL}, + { sr_kemi_sqlang_exec_func_816, NULL}, + { sr_kemi_sqlang_exec_func_817, NULL}, + { sr_kemi_sqlang_exec_func_818, NULL}, + { sr_kemi_sqlang_exec_func_819, NULL}, + { sr_kemi_sqlang_exec_func_820, NULL}, + { sr_kemi_sqlang_exec_func_821, NULL}, + { sr_kemi_sqlang_exec_func_822, NULL}, + { sr_kemi_sqlang_exec_func_823, NULL}, + { sr_kemi_sqlang_exec_func_824, NULL}, + { sr_kemi_sqlang_exec_func_825, NULL}, + { sr_kemi_sqlang_exec_func_826, NULL}, + { sr_kemi_sqlang_exec_func_827, NULL}, + { sr_kemi_sqlang_exec_func_828, NULL}, + { sr_kemi_sqlang_exec_func_829, NULL}, + { sr_kemi_sqlang_exec_func_830, NULL}, + { sr_kemi_sqlang_exec_func_831, NULL}, + { sr_kemi_sqlang_exec_func_832, NULL}, + { sr_kemi_sqlang_exec_func_833, NULL}, + { sr_kemi_sqlang_exec_func_834, NULL}, + { sr_kemi_sqlang_exec_func_835, NULL}, + { sr_kemi_sqlang_exec_func_836, NULL}, + { sr_kemi_sqlang_exec_func_837, NULL}, + { sr_kemi_sqlang_exec_func_838, NULL}, + { sr_kemi_sqlang_exec_func_839, NULL}, + { sr_kemi_sqlang_exec_func_840, NULL}, + { sr_kemi_sqlang_exec_func_841, NULL}, + { sr_kemi_sqlang_exec_func_842, NULL}, + { sr_kemi_sqlang_exec_func_843, NULL}, + { sr_kemi_sqlang_exec_func_844, NULL}, + { sr_kemi_sqlang_exec_func_845, NULL}, + { sr_kemi_sqlang_exec_func_846, NULL}, + { sr_kemi_sqlang_exec_func_847, NULL}, + { sr_kemi_sqlang_exec_func_848, NULL}, + { sr_kemi_sqlang_exec_func_849, NULL}, + { sr_kemi_sqlang_exec_func_850, NULL}, + { sr_kemi_sqlang_exec_func_851, NULL}, + { sr_kemi_sqlang_exec_func_852, NULL}, + { sr_kemi_sqlang_exec_func_853, NULL}, + { sr_kemi_sqlang_exec_func_854, NULL}, + { sr_kemi_sqlang_exec_func_855, NULL}, + { sr_kemi_sqlang_exec_func_856, NULL}, + { sr_kemi_sqlang_exec_func_857, NULL}, + { sr_kemi_sqlang_exec_func_858, NULL}, + { sr_kemi_sqlang_exec_func_859, NULL}, + { sr_kemi_sqlang_exec_func_860, NULL}, + { sr_kemi_sqlang_exec_func_861, NULL}, + { sr_kemi_sqlang_exec_func_862, NULL}, + { sr_kemi_sqlang_exec_func_863, NULL}, + { sr_kemi_sqlang_exec_func_864, NULL}, + { sr_kemi_sqlang_exec_func_865, NULL}, + { sr_kemi_sqlang_exec_func_866, NULL}, + { sr_kemi_sqlang_exec_func_867, NULL}, + { sr_kemi_sqlang_exec_func_868, NULL}, + { sr_kemi_sqlang_exec_func_869, NULL}, + { sr_kemi_sqlang_exec_func_870, NULL}, + { sr_kemi_sqlang_exec_func_871, NULL}, + { sr_kemi_sqlang_exec_func_872, NULL}, + { sr_kemi_sqlang_exec_func_873, NULL}, + { sr_kemi_sqlang_exec_func_874, NULL}, + { sr_kemi_sqlang_exec_func_875, NULL}, + { sr_kemi_sqlang_exec_func_876, NULL}, + { sr_kemi_sqlang_exec_func_877, NULL}, + { sr_kemi_sqlang_exec_func_878, NULL}, + { sr_kemi_sqlang_exec_func_879, NULL}, + { sr_kemi_sqlang_exec_func_880, NULL}, + { sr_kemi_sqlang_exec_func_881, NULL}, + { sr_kemi_sqlang_exec_func_882, NULL}, + { sr_kemi_sqlang_exec_func_883, NULL}, + { sr_kemi_sqlang_exec_func_884, NULL}, + { sr_kemi_sqlang_exec_func_885, NULL}, + { sr_kemi_sqlang_exec_func_886, NULL}, + { sr_kemi_sqlang_exec_func_887, NULL}, + { sr_kemi_sqlang_exec_func_888, NULL}, + { sr_kemi_sqlang_exec_func_889, NULL}, + { sr_kemi_sqlang_exec_func_890, NULL}, + { sr_kemi_sqlang_exec_func_891, NULL}, + { sr_kemi_sqlang_exec_func_892, NULL}, + { sr_kemi_sqlang_exec_func_893, NULL}, + { sr_kemi_sqlang_exec_func_894, NULL}, + { sr_kemi_sqlang_exec_func_895, NULL}, + { sr_kemi_sqlang_exec_func_896, NULL}, + { sr_kemi_sqlang_exec_func_897, NULL}, + { sr_kemi_sqlang_exec_func_898, NULL}, + { sr_kemi_sqlang_exec_func_899, NULL}, + { sr_kemi_sqlang_exec_func_900, NULL}, + { sr_kemi_sqlang_exec_func_901, NULL}, + { sr_kemi_sqlang_exec_func_902, NULL}, + { sr_kemi_sqlang_exec_func_903, NULL}, + { sr_kemi_sqlang_exec_func_904, NULL}, + { sr_kemi_sqlang_exec_func_905, NULL}, + { sr_kemi_sqlang_exec_func_906, NULL}, + { sr_kemi_sqlang_exec_func_907, NULL}, + { sr_kemi_sqlang_exec_func_908, NULL}, + { sr_kemi_sqlang_exec_func_909, NULL}, + { sr_kemi_sqlang_exec_func_910, NULL}, + { sr_kemi_sqlang_exec_func_911, NULL}, + { sr_kemi_sqlang_exec_func_912, NULL}, + { sr_kemi_sqlang_exec_func_913, NULL}, + { sr_kemi_sqlang_exec_func_914, NULL}, + { sr_kemi_sqlang_exec_func_915, NULL}, + { sr_kemi_sqlang_exec_func_916, NULL}, + { sr_kemi_sqlang_exec_func_917, NULL}, + { sr_kemi_sqlang_exec_func_918, NULL}, + { sr_kemi_sqlang_exec_func_919, NULL}, + { sr_kemi_sqlang_exec_func_920, NULL}, + { sr_kemi_sqlang_exec_func_921, NULL}, + { sr_kemi_sqlang_exec_func_922, NULL}, + { sr_kemi_sqlang_exec_func_923, NULL}, + { sr_kemi_sqlang_exec_func_924, NULL}, + { sr_kemi_sqlang_exec_func_925, NULL}, + { sr_kemi_sqlang_exec_func_926, NULL}, + { sr_kemi_sqlang_exec_func_927, NULL}, + { sr_kemi_sqlang_exec_func_928, NULL}, + { sr_kemi_sqlang_exec_func_929, NULL}, + { sr_kemi_sqlang_exec_func_930, NULL}, + { sr_kemi_sqlang_exec_func_931, NULL}, + { sr_kemi_sqlang_exec_func_932, NULL}, + { sr_kemi_sqlang_exec_func_933, NULL}, + { sr_kemi_sqlang_exec_func_934, NULL}, + { sr_kemi_sqlang_exec_func_935, NULL}, + { sr_kemi_sqlang_exec_func_936, NULL}, + { sr_kemi_sqlang_exec_func_937, NULL}, + { sr_kemi_sqlang_exec_func_938, NULL}, + { sr_kemi_sqlang_exec_func_939, NULL}, + { sr_kemi_sqlang_exec_func_940, NULL}, + { sr_kemi_sqlang_exec_func_941, NULL}, + { sr_kemi_sqlang_exec_func_942, NULL}, + { sr_kemi_sqlang_exec_func_943, NULL}, + { sr_kemi_sqlang_exec_func_944, NULL}, + { sr_kemi_sqlang_exec_func_945, NULL}, + { sr_kemi_sqlang_exec_func_946, NULL}, + { sr_kemi_sqlang_exec_func_947, NULL}, + { sr_kemi_sqlang_exec_func_948, NULL}, + { sr_kemi_sqlang_exec_func_949, NULL}, + { sr_kemi_sqlang_exec_func_950, NULL}, + { sr_kemi_sqlang_exec_func_951, NULL}, + { sr_kemi_sqlang_exec_func_952, NULL}, + { sr_kemi_sqlang_exec_func_953, NULL}, + { sr_kemi_sqlang_exec_func_954, NULL}, + { sr_kemi_sqlang_exec_func_955, NULL}, + { sr_kemi_sqlang_exec_func_956, NULL}, + { sr_kemi_sqlang_exec_func_957, NULL}, + { sr_kemi_sqlang_exec_func_958, NULL}, + { sr_kemi_sqlang_exec_func_959, NULL}, + { sr_kemi_sqlang_exec_func_960, NULL}, + { sr_kemi_sqlang_exec_func_961, NULL}, + { sr_kemi_sqlang_exec_func_962, NULL}, + { sr_kemi_sqlang_exec_func_963, NULL}, + { sr_kemi_sqlang_exec_func_964, NULL}, + { sr_kemi_sqlang_exec_func_965, NULL}, + { sr_kemi_sqlang_exec_func_966, NULL}, + { sr_kemi_sqlang_exec_func_967, NULL}, + { sr_kemi_sqlang_exec_func_968, NULL}, + { sr_kemi_sqlang_exec_func_969, NULL}, + { sr_kemi_sqlang_exec_func_970, NULL}, + { sr_kemi_sqlang_exec_func_971, NULL}, + { sr_kemi_sqlang_exec_func_972, NULL}, + { sr_kemi_sqlang_exec_func_973, NULL}, + { sr_kemi_sqlang_exec_func_974, NULL}, + { sr_kemi_sqlang_exec_func_975, NULL}, + { sr_kemi_sqlang_exec_func_976, NULL}, + { sr_kemi_sqlang_exec_func_977, NULL}, + { sr_kemi_sqlang_exec_func_978, NULL}, + { sr_kemi_sqlang_exec_func_979, NULL}, + { sr_kemi_sqlang_exec_func_980, NULL}, + { sr_kemi_sqlang_exec_func_981, NULL}, + { sr_kemi_sqlang_exec_func_982, NULL}, + { sr_kemi_sqlang_exec_func_983, NULL}, + { sr_kemi_sqlang_exec_func_984, NULL}, + { sr_kemi_sqlang_exec_func_985, NULL}, + { sr_kemi_sqlang_exec_func_986, NULL}, + { sr_kemi_sqlang_exec_func_987, NULL}, + { sr_kemi_sqlang_exec_func_988, NULL}, + { sr_kemi_sqlang_exec_func_989, NULL}, + { sr_kemi_sqlang_exec_func_990, NULL}, + { sr_kemi_sqlang_exec_func_991, NULL}, + { sr_kemi_sqlang_exec_func_992, NULL}, + { sr_kemi_sqlang_exec_func_993, NULL}, + { sr_kemi_sqlang_exec_func_994, NULL}, + { sr_kemi_sqlang_exec_func_995, NULL}, + { sr_kemi_sqlang_exec_func_996, NULL}, + { sr_kemi_sqlang_exec_func_997, NULL}, + { sr_kemi_sqlang_exec_func_998, NULL}, + { sr_kemi_sqlang_exec_func_999, NULL}, + { sr_kemi_sqlang_exec_func_1000, NULL}, + { sr_kemi_sqlang_exec_func_1001, NULL}, + { sr_kemi_sqlang_exec_func_1002, NULL}, + { sr_kemi_sqlang_exec_func_1003, NULL}, + { sr_kemi_sqlang_exec_func_1004, NULL}, + { sr_kemi_sqlang_exec_func_1005, NULL}, + { sr_kemi_sqlang_exec_func_1006, NULL}, + { sr_kemi_sqlang_exec_func_1007, NULL}, + { sr_kemi_sqlang_exec_func_1008, NULL}, + { sr_kemi_sqlang_exec_func_1009, NULL}, + { sr_kemi_sqlang_exec_func_1010, NULL}, + { sr_kemi_sqlang_exec_func_1011, NULL}, + { sr_kemi_sqlang_exec_func_1012, NULL}, + { sr_kemi_sqlang_exec_func_1013, NULL}, + { sr_kemi_sqlang_exec_func_1014, NULL}, + { sr_kemi_sqlang_exec_func_1015, NULL}, + { sr_kemi_sqlang_exec_func_1016, NULL}, + { sr_kemi_sqlang_exec_func_1017, NULL}, + { sr_kemi_sqlang_exec_func_1018, NULL}, + { sr_kemi_sqlang_exec_func_1019, NULL}, + { sr_kemi_sqlang_exec_func_1020, NULL}, + { sr_kemi_sqlang_exec_func_1021, NULL}, + { sr_kemi_sqlang_exec_func_1022, NULL}, + { sr_kemi_sqlang_exec_func_1023, NULL}, + {NULL, NULL} +}; + +/** + * + */ +sr_kemi_t *sr_kemi_sqlang_export_get(int idx) +{ + if(idx<0 || idx>=SR_KEMI_SQLANG_EXPORT_SIZE) + return NULL; + return _sr_kemi_sqlang_export_list[idx].ket; +} + +/** + * + */ +SQFUNCTION sr_kemi_sqlang_export_associate(sr_kemi_t *ket) +{ + int i; + for(i=0; i +#include "../../core/kemi.h" + +#define SR_KEMI_SQLANG_EXPORT_SIZE 1024 + +typedef struct sr_kemi_sqlang_export { + SQFUNCTION pfunc; + sr_kemi_t *ket; +} sr_kemi_sqlang_export_t; + +sr_kemi_t *sr_kemi_sqlang_export_get(int idx); +SQFUNCTION sr_kemi_sqlang_export_associate(sr_kemi_t *ket); + +#endif diff --git a/src/modules/app_sqlang/app_sqlang_mod.c b/src/modules/app_sqlang/app_sqlang_mod.c new file mode 100644 index 00000000000..7d0240fb500 --- /dev/null +++ b/src/modules/app_sqlang/app_sqlang_mod.c @@ -0,0 +1,582 @@ +/** + * Copyright (C) 2017 Daniel-Constantin Mierla (asipto.com) + * + * This file is part of Kamailio, a free SIP server. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version + * + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include +#include +#include +#include + +#include "../../core/sr_module.h" +#include "../../core/dprint.h" +#include "../../core/mod_fix.h" +#include "../../core/kemi.h" + +#include "app_sqlang_api.h" + +MODULE_VERSION + +static int mod_init(void); +static int child_init(int rank); +static void mod_destroy(void); + +static int w_app_sqlang_dostring(sip_msg_t *msg, char *script, char *extra); +static int w_app_sqlang_dofile(sip_msg_t *msg, char *script, char *extra); +static int w_app_sqlang_runstring(sip_msg_t *msg, char *script, char *extra); +static int w_app_sqlang_run(sip_msg_t *msg, char *func, char *p1, char *p2, + char *p3); +static int w_app_sqlang_run0(sip_msg_t *msg, char *func, char *p1, char *p2, + char *p3); +static int w_app_sqlang_run1(sip_msg_t *msg, char *func, char *p1, char *p2, + char *p3); +static int w_app_sqlang_run2(sip_msg_t *msg, char *func, char *p1, char *p2, + char *p3); +static int w_app_sqlang_run3(sip_msg_t *msg, char *func, char *p1, char *p2, + char *p3); + +static int fixup_sqlang_run(void** param, int param_no); + +extern str _sr_sqlang_load_file; + +/* clang-format off */ +static cmd_export_t cmds[]={ + {"sqlang_dostring", (cmd_function)w_app_sqlang_dostring, 1, fixup_spve_null, + 0, ANY_ROUTE}, + {"sqlang_dofile", (cmd_function)w_app_sqlang_dofile, 1, fixup_spve_null, + 0, ANY_ROUTE}, + {"sqlang_runstring", (cmd_function)w_app_sqlang_runstring, 1, fixup_spve_null, + 0, ANY_ROUTE}, + {"sqlang_run", (cmd_function)w_app_sqlang_run0, 1, fixup_sqlang_run, + 0, ANY_ROUTE}, + {"sqlang_run", (cmd_function)w_app_sqlang_run1, 2, fixup_sqlang_run, + 0, ANY_ROUTE}, + {"sqlang_run", (cmd_function)w_app_sqlang_run2, 3, fixup_sqlang_run, + 0, ANY_ROUTE}, + {"sqlang_run", (cmd_function)w_app_sqlang_run3, 4, fixup_sqlang_run, + 0, ANY_ROUTE}, + + {0, 0, 0, 0, 0, 0} +}; + +static param_export_t params[]={ + {"load", PARAM_STR, &_sr_sqlang_load_file}, + {0, 0, 0} +}; + +struct module_exports exports = { + "app_sqlang", + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, + params, + 0, + 0, /* exported MI functions */ + 0, /* exported pseudo-variables */ + 0, /* extra processes */ + mod_init, /* module initialization function */ + 0, /* response function */ + mod_destroy, /* destroy function */ + child_init /* per child init function */ +}; +/* clang-format on */ + +/** + * init module function + */ +static int mod_init(void) +{ + if(sqlang_sr_init_mod()<0) + return -1; + + if(app_sqlang_init_rpc()<0) { + LM_ERR("failed to register RPC commands\n"); + return -1; + } + + return 0; +} + +/** + * init module children + */ +static int child_init(int rank) +{ + if(rank==PROC_INIT) + return 0; + return sqlang_sr_init_child(); +} + +/** + * destroy module function + */ +static void mod_destroy(void) +{ + sqlang_sr_destroy(); +} + +/** + * + */ +int sr_kemi_config_engine_sqlang(sip_msg_t *msg, int rtype, str *rname, + str *rparam) +{ + int ret; + + ret = -1; + if(rtype==REQUEST_ROUTE) { + if(rname!=NULL && rname->s!=NULL) { + ret = app_sqlang_run_ex(msg, rname->s, + (rparam && rparam->s)?rparam->s:NULL, NULL, NULL, 0); + } else { + ret = app_sqlang_run_ex(msg, "ksr_request_route", NULL, NULL, NULL, 1); + } + } else if(rtype==CORE_ONREPLY_ROUTE) { + ret = app_sqlang_run_ex(msg, "ksr_reply_route", NULL, NULL, NULL, 0); + } else if(rtype==BRANCH_ROUTE) { + if(rname!=NULL && rname->s!=NULL) { + ret = app_sqlang_run_ex(msg, rname->s, NULL, NULL, NULL, 0); + } + } else if(rtype==FAILURE_ROUTE) { + if(rname!=NULL && rname->s!=NULL) { + ret = app_sqlang_run_ex(msg, rname->s, NULL, NULL, NULL, 0); + } + } else if(rtype==BRANCH_FAILURE_ROUTE) { + if(rname!=NULL && rname->s!=NULL) { + ret = app_sqlang_run_ex(msg, rname->s, NULL, NULL, NULL, 0); + } + } else if(rtype==TM_ONREPLY_ROUTE) { + if(rname!=NULL && rname->s!=NULL) { + ret = app_sqlang_run_ex(msg, rname->s, NULL, NULL, NULL, 0); + } + } else if(rtype==ONSEND_ROUTE) { + ret = app_sqlang_run_ex(msg, "ksr_onsend_route", NULL, NULL, NULL, 0); + } else if(rtype==EVENT_ROUTE) { + if(rname!=NULL && rname->s!=NULL) { + ret = app_sqlang_run_ex(msg, rname->s, + (rparam && rparam->s)?rparam->s:NULL, NULL, NULL, 0); + } + } else { + if(rname!=NULL) { + LM_ERR("route type %d with name [%.*s] not implemented\n", + rtype, rname->len, rname->s); + } else { + LM_ERR("route type %d with no name not implemented\n", + rtype); + } + } + + if(rname!=NULL) { + LM_DBG("execution of route type %d with name [%.*s] returned %d\n", + rtype, rname->len, rname->s, ret); + } else { + LM_DBG("execution of route type %d with no name returned %d\n", + rtype, ret); + } + + return 1; +} + +static char _sqlang_buf_stack[4][512]; + +/** + * + */ +static int ki_app_sqlang_dostring(sip_msg_t *msg, str *script) +{ + if(script==NULL || script->s==NULL || script->len>=511) { + LM_ERR("script too short or too long %d\n", script->len); + return -1; + } + if(!sqlang_sr_initialized()) + { + LM_ERR("sqlang env not intitialized"); + return -1; + } + memcpy(_sqlang_buf_stack[0], script->s, script->len); + _sqlang_buf_stack[0][script->len] = '\0'; + return app_sqlang_dostring(msg, _sqlang_buf_stack[0]); +} + +/** + * + */ +static int w_app_sqlang_dostring(struct sip_msg *msg, char *script, char *extra) +{ + str s; + if(fixup_get_svalue(msg, (gparam_p)script, &s)<0) + { + LM_ERR("cannot get the script\n"); + return -1; + } + return ki_app_sqlang_dostring(msg, &s); +} + +/** + * + */ +static int ki_app_sqlang_dofile(sip_msg_t *msg, str *script) +{ + if(script==NULL || script->s==NULL || script->len>=511) { + LM_ERR("script too short or too long %d\n", script->len); + return -1; + } + if(!sqlang_sr_initialized()) + { + LM_ERR("sqlang env not intitialized"); + return -1; + } + memcpy(_sqlang_buf_stack[0], script->s, script->len); + _sqlang_buf_stack[0][script->len] = '\0'; + return app_sqlang_dofile(msg, _sqlang_buf_stack[0]); +} + +/** + * + */ +static int w_app_sqlang_dofile(struct sip_msg *msg, char *script, char *extra) +{ + str s; + if(fixup_get_svalue(msg, (gparam_p)script, &s)<0) + { + LM_ERR("cannot get the script\n"); + return -1; + } + return ki_app_sqlang_dofile(msg, &s); +} + +/** + * + */ +static int ki_app_sqlang_runstring(sip_msg_t *msg, str *script) +{ + if(script==NULL || script->s==NULL || script->len>=511) { + LM_ERR("script too short or too long %d\n", script->len); + return -1; + } + if(!sqlang_sr_initialized()) + { + LM_ERR("sqlang env not intitialized"); + return -1; + } + memcpy(_sqlang_buf_stack[0], script->s, script->len); + _sqlang_buf_stack[0][script->len] = '\0'; + return app_sqlang_runstring(msg, _sqlang_buf_stack[0]); +} + +/** + * + */ +static int w_app_sqlang_runstring(struct sip_msg *msg, char *script, char *extra) +{ + str s; + if(fixup_get_svalue(msg, (gparam_p)script, &s)<0) + { + LM_ERR("cannot get the script\n"); + return -1; + } + return ki_app_sqlang_runstring(msg, &s); +} + +/** + * + */ +static int w_app_sqlang_run(struct sip_msg *msg, char *func, char *p1, char *p2, + char *p3) +{ + str s; + if(!sqlang_sr_initialized()) + { + LM_ERR("sqlang env not intitialized"); + return -1; + } + if(fixup_get_svalue(msg, (gparam_p)func, &s)<0) + { + LM_ERR("cannot get the function\n"); + return -1; + } + if(s.len>=511) + { + LM_ERR("function too long %d\n", s.len); + return -1; + } + memcpy(_sqlang_buf_stack[0], s.s, s.len); + _sqlang_buf_stack[0][s.len] = '\0'; + + if(p1!=NULL) + { + if(fixup_get_svalue(msg, (gparam_p)p1, &s)<0) + { + LM_ERR("cannot get p1\n"); + return -1; + } + if(s.len>=511) + { + LM_ERR("p1 too long %d\n", s.len); + return -1; + } + memcpy(_sqlang_buf_stack[1], s.s, s.len); + _sqlang_buf_stack[1][s.len] = '\0'; + + if(p2!=NULL) + { + if(fixup_get_svalue(msg, (gparam_p)p2, &s)<0) + { + LM_ERR("cannot get p2\n"); + return -1; + } + if(s.len>=511) + { + LM_ERR("p2 too long %d\n", s.len); + return -1; + } + memcpy(_sqlang_buf_stack[2], s.s, s.len); + _sqlang_buf_stack[2][s.len] = '\0'; + + if(p3!=NULL) + { + if(fixup_get_svalue(msg, (gparam_p)p3, &s)<0) + { + LM_ERR("cannot get p3\n"); + return -1; + } + if(s.len>=511) + { + LM_ERR("p3 too long %d\n", s.len); + return -1; + } + memcpy(_sqlang_buf_stack[3], s.s, s.len); + _sqlang_buf_stack[3][s.len] = '\0'; + } + } else { + p3 = NULL; + } + } else { + p2 = NULL; + p3 = NULL; + } + + return app_sqlang_run(msg, _sqlang_buf_stack[0], + (p1!=NULL)?_sqlang_buf_stack[1]:NULL, + (p2!=NULL)?_sqlang_buf_stack[2]:NULL, + (p3!=NULL)?_sqlang_buf_stack[3]:NULL); +} + +static int w_app_sqlang_run0(struct sip_msg *msg, char *func, char *p1, char *p2, + char *p3) +{ + return w_app_sqlang_run(msg, func, NULL, NULL, NULL); +} + +static int w_app_sqlang_run1(struct sip_msg *msg, char *func, char *p1, char *p2, + char *p3) +{ + return w_app_sqlang_run(msg, func, p1, NULL, NULL); +} + +static int w_app_sqlang_run2(struct sip_msg *msg, char *func, char *p1, char *p2, + char *p3) +{ + return w_app_sqlang_run(msg, func, p1, p2, NULL); +} + +static int w_app_sqlang_run3(struct sip_msg *msg, char *func, char *p1, char *p2, + char *p3) +{ + return w_app_sqlang_run(msg, func, p1, p2, p3); +} + +static int fixup_sqlang_run(void** param, int param_no) +{ + return fixup_spve_null(param, 1); +} + +/** + * + */ +static int ki_app_sqlang_run(sip_msg_t *msg, str *func) +{ + if(func==NULL || func->s==NULL || func->len<0) { + LM_ERR("invalid function name\n"); + return -1; + } + if(func->s[func->len]!='\0') { + LM_ERR("invalid terminated function name\n"); + return -1; + } + return app_sqlang_run(msg, func->s, NULL, NULL, NULL); + +} + +/** + * + */ +static int ki_app_sqlang_run_p1(sip_msg_t *msg, str *func, str *p1) +{ + if(func==NULL || func->s==NULL || func->len<=0) { + LM_ERR("invalid function name\n"); + return -1; + } + if(func->s[func->len]!='\0') { + LM_ERR("invalid terminated function name\n"); + return -1; + } + if(p1==NULL || p1->s==NULL || p1->len<0) { + LM_ERR("invalid p1 value\n"); + return -1; + } + if(p1->s[p1->len]!='\0') { + LM_ERR("invalid terminated p1 value\n"); + return -1; + } + return app_sqlang_run(msg, func->s, p1->s, NULL, NULL); +} + +/** + * + */ +static int ki_app_sqlang_run_p2(sip_msg_t *msg, str *func, str *p1, str *p2) +{ + if(func==NULL || func->s==NULL || func->len<=0) { + LM_ERR("invalid function name\n"); + return -1; + } + if(func->s[func->len]!='\0') { + LM_ERR("invalid terminated function name\n"); + return -1; + } + if(p1==NULL || p1->s==NULL || p1->len<0) { + LM_ERR("invalid p1 value\n"); + return -1; + } + if(p1->s[p1->len]!='\0') { + LM_ERR("invalid terminated p1 value\n"); + return -1; + } + if(p2==NULL || p2->s==NULL || p2->len<0) { + LM_ERR("invalid p2 value\n"); + return -1; + } + if(p2->s[p2->len]!='\0') { + LM_ERR("invalid terminated p2 value\n"); + return -1; + } + return app_sqlang_run(msg, func->s, p1->s, p2->s, NULL); +} + +/** + * + */ +static int ki_app_sqlang_run_p3(sip_msg_t *msg, str *func, str *p1, str *p2, str *p3) +{ + if(func==NULL || func->s==NULL || func->len<=0) { + LM_ERR("invalid function name\n"); + return -1; + } + if(func->s[func->len]!='\0') { + LM_ERR("invalid terminated function name\n"); + return -1; + } + if(p1==NULL || p1->s==NULL || p1->len<0) { + LM_ERR("invalid p1 value\n"); + return -1; + } + if(p1->s[p1->len]!='\0') { + LM_ERR("invalid terminated p1 value\n"); + return -1; + } + if(p2==NULL || p2->s==NULL || p2->len<0) { + LM_ERR("invalid p2 value\n"); + return -1; + } + if(p2->s[p2->len]!='\0') { + LM_ERR("invalid terminated p2 value\n"); + return -1; + } + if(p3==NULL || p3->s==NULL || p3->len<0) { + LM_ERR("invalid p3 value\n"); + return -1; + } + if(p3->s[p3->len]!='\0') { + LM_ERR("invalid terminated p3 value\n"); + return -1; + } + return app_sqlang_run(msg, func->s, p1->s, p2->s, p3->s); +} + +/** + * + */ +/* clang-format off */ +static sr_kemi_t sr_kemi_app_sqlang_exports[] = { + { str_init("app_sqlang"), str_init("dostring"), + SR_KEMIP_INT, ki_app_sqlang_dostring, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("app_sqlang"), str_init("dofile"), + SR_KEMIP_INT, ki_app_sqlang_dofile, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("app_sqlang"), str_init("runstring"), + SR_KEMIP_INT, ki_app_sqlang_runstring, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("app_sqlang"), str_init("run"), + SR_KEMIP_INT, ki_app_sqlang_run, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("app_sqlang"), str_init("run_p1"), + SR_KEMIP_INT, ki_app_sqlang_run_p1, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("app_sqlang"), str_init("run_p2"), + SR_KEMIP_INT, ki_app_sqlang_run_p2, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("app_sqlang"), str_init("run_p3"), + SR_KEMIP_INT, ki_app_sqlang_run_p3, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, + SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + + { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } } +}; +/* clang-format on */ + + +/** + * + */ +int mod_register(char *path, int *dlflags, void *p1, void *p2) +{ + str ename = str_init("sqlang"); + + *dlflags = RTLD_NOW | RTLD_GLOBAL; + + sr_kemi_eng_register(&ename, sr_kemi_config_engine_sqlang); + sr_kemi_modules_add(sr_kemi_app_sqlang_exports); + + return 0; +} diff --git a/src/modules/app_sqlang/doc/Makefile b/src/modules/app_sqlang/doc/Makefile new file mode 100644 index 00000000000..b07f37aaac2 --- /dev/null +++ b/src/modules/app_sqlang/doc/Makefile @@ -0,0 +1,4 @@ +docs = app_sqlang.xml + +docbook_dir = ../../../../doc/docbook +include $(docbook_dir)/Makefile.module diff --git a/src/modules/app_sqlang/doc/app_sqlang.xml b/src/modules/app_sqlang/doc/app_sqlang.xml new file mode 100644 index 00000000000..e27a2ecf51f --- /dev/null +++ b/src/modules/app_sqlang/doc/app_sqlang.xml @@ -0,0 +1,36 @@ + + + +%docentities; + +]> + + + + app_sqlang Module + &kamailioname; + + + Daniel-Constantin + Mierla + asipto.com + + + Daniel-Constantin + Mierla + miconda@gmail.com + + + + 2017 + Daniel-Constantin Mierla (asipto.com) + + + + + + + diff --git a/src/modules/app_sqlang/doc/app_sqlang_admin.xml b/src/modules/app_sqlang/doc/app_sqlang_admin.xml new file mode 100644 index 00000000000..7d8d0dc0102 --- /dev/null +++ b/src/modules/app_sqlang/doc/app_sqlang_admin.xml @@ -0,0 +1,288 @@ + + + +%docentities; + +]> + + + + + + &adminguide; + +
+ Overview + + This module allows executing Squirrel Language (SQLang) scripts from + config file. It exports all KEMI functions to SQLang in order to access + the current processed SIP message. These functions are within SQLang + object 'KSR' (a table object). + + + It includes the Squirrel Language engine (http://www.squirrel-lang.org). + Exported API from SIP router to SQLang is documented in the dokuwiki. + + + The module has two SQLang contexts: + + + + first is used for functions sqlang_dofile() + and sqlang_dostring(). + + + + + second is used for function sqlan_run() + and parameter 'load'. Therefore sqlang_run() cannot execute functions + from scripts loaded via sqlang_dofile() in config. This is kind of + caching mode, avoiding reading file every time, but you must be sure + you do not have someting that is executed by default and requires + access to SIP message. This environment is also used by KEMI + framework for the config SIP routing functions. + + + + +
+
+ Dependencies +
+ &kamailio; Modules + + The following modules must be loaded before this module: + + + + none. + + + + +
+
+ External Libraries or Applications + + The following libraries or applications must be installed before running + &kamailio; with this module loaded: + + + + none + + + + +
+
+
+ Parameters +
+ <varname>load</varname> (str) + + Set the path to the SQLang file to be loaded at startup. Then you + can use sqlang_run(function, params) to execute a function from the + script at runtime. If you use it for KEMI configuration, + then it has to include the requited functions. + + + + Default value is null. + + + + Set <varname>load</varname> parameter + +... +modparam("app_sqlang", "load", "/usr/local/etc/kamailio/sqlang/myscript.sq") +... + + +
+ +
+ +
+ Functions +
+ + <function moreinfo="none">sqlang_dofile(path)</function> + + + Note: not implemented yet. + + + Execute the SQLang script stored in 'path'. The parameter can be + a string with pseudo-variables evaluated at runtime. + + + <function>sqlang_dofile</function> usage + +... +sqlang_dofile("/usr/local/etc/kamailio/sqlang/myscript.sq"); +... + + +
+ +
+ + <function moreinfo="none">sqlang_dostring(script)</function> + + + Note: not implemented yet. + + + Execute the Lua script stored in parameter. The parameter can be + a string with pseudo-variables. + + + <function>sqlang_dostring</function> usage + +... +if(!sqlang_dostring('KSR.dbg("test message\n")')) +{ + xdbg("SCRIPT: failed to execute js script!\n"); +} +... + + +
+ +
+ + <function moreinfo="none">sqlang_run(function [, params])</function> + + + Execute the JS function 'func' giving params as parameters. There + can be up to 3 string parameters. The function must exist in the + script loaded at startup via parameter 'load'. Parameters can be + strings with pseudo-variables that are evaluated at runtime. + + + <function>sqlang_run</function> usage + +... +if(!sqlang_run("js_append_fu_to_reply")) +{ + xdbg("SCRIPT: failed to execute js function!\n"); +} +... +sqlang_run("js_funcx", "$rU", "2"); +... + + +
+ +
+ + <function moreinfo="none">sqlang_runstring(script)</function> + + + Note: not implemented yet. + + + Execute the SQLang script stored in parameter. The parameter can be + a string with pseudo-variables. The script is executed in JS context + specific to loaded JS files at startup. + + + <function>sqlang_runstring</function> usage + +... +if(!sqlang_runstring('KSR.dbg("Hello World from $fU\n")')) +{ + xdbg("failed to execute js script!\n"); +} +... + + +
+ +
+ +
+ RPC Commands +
+ + <function moreinfo="none">app_swlang.reload</function> + + + Marks the need to reload the SQLang script pointed by 'load' + parameter.The actual reload is done by every working process when + the next call to sqlang_run() function or KEMI config is executed. + + + Name: app_sqlang.reload + + Parameters: none + + Example: + + +... +&kamcmd; app_sqlang.reload +... + +
+
+ + <function moreinfo="none">app_sqlang.api_list</function> + + + List the functions available via Kemi framework. + + + Name: app_sqlang.api_list + + Parameters: none + + Example: + + +... +&kamcmd; app_sqlang.api_list +... + +
+
+ +
+ Example of usage + + Create your SQLang script and stored on file system, + say: '/usr/local/etc/kamailio/sqlang/myscript.sq'. + + +... +function sr_append_fu_to_reply() +{ + KSR.hdr.append_to_reply("P-From: " + KSR.pv.get("$fu") + "\r\n"); +} +... + + + Load the script via parameter 'load' and execute function + via sqlang_run(...). + + +... +modparam("app_sqlang", "load", "/usr/local/etc/kamailio/sqlang/myscript.sq") +... +request_route { + ... + if(!sqlang_run("sr_append_fu_to_reply")) + { + xdbg("SCRIPT: failed to execute js function!\n"); + } + ... +} +... + +
+
+ diff --git a/src/modules/app_sqlang/squirrel/include/sqconfig.h b/src/modules/app_sqlang/squirrel/include/sqconfig.h new file mode 100644 index 00000000000..857a7d00db1 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/include/sqconfig.h @@ -0,0 +1,146 @@ + +#ifdef _SQ64 + +#ifdef _MSC_VER +typedef __int64 SQInteger; +typedef unsigned __int64 SQUnsignedInteger; +typedef unsigned __int64 SQHash; /*should be the same size of a pointer*/ +#else +typedef long long SQInteger; +typedef unsigned long long SQUnsignedInteger; +typedef unsigned long long SQHash; /*should be the same size of a pointer*/ +#endif +typedef int SQInt32; +typedef unsigned int SQUnsignedInteger32; +#else +typedef int SQInteger; +typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/ +typedef unsigned int SQUnsignedInteger32; /*must be 32 bits(also on 64bits processors)*/ +typedef unsigned int SQUnsignedInteger; +typedef unsigned int SQHash; /*should be the same size of a pointer*/ +#endif + + +#ifdef SQUSEDOUBLE +typedef double SQFloat; +#else +typedef float SQFloat; +#endif + +#if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64) +#ifdef _MSC_VER +typedef __int64 SQRawObjectVal; //must be 64bits +#else +typedef long long SQRawObjectVal; //must be 64bits +#endif +#define SQ_OBJECT_RAWINIT() { _unVal.raw = 0; } +#else +typedef SQUnsignedInteger SQRawObjectVal; //is 32 bits on 32 bits builds and 64 bits otherwise +#define SQ_OBJECT_RAWINIT() +#endif + +#ifndef SQ_ALIGNMENT // SQ_ALIGNMENT shall be less than or equal to SQ_MALLOC alignments, and its value shall be power of 2. +#if defined(SQUSEDOUBLE) || defined(_SQ64) +#define SQ_ALIGNMENT 8 +#else +#define SQ_ALIGNMENT 4 +#endif +#endif + +typedef void* SQUserPointer; +typedef SQUnsignedInteger SQBool; +typedef SQInteger SQRESULT; + +#ifdef SQUNICODE +#include +#include + + +typedef wchar_t SQChar; + + +#define scstrcmp wcscmp +#ifdef _WIN32 +#define scsprintf _snwprintf +#else +#define scsprintf swprintf +#endif +#define scstrlen wcslen +#define scstrtod wcstod +#ifdef _SQ64 +#define scstrtol wcstoll +#else +#define scstrtol wcstol +#endif +#define scstrtoul wcstoul +#define scvsprintf vswprintf +#define scstrstr wcsstr +#define scprintf wprintf + +#ifdef _WIN32 +#define WCHAR_SIZE 2 +#define WCHAR_SHIFT_MUL 1 +#define MAX_CHAR 0xFFFF +#else +#define WCHAR_SIZE 4 +#define WCHAR_SHIFT_MUL 2 +#define MAX_CHAR 0xFFFFFFFF +#endif + +#define _SC(a) L##a + + +#define scisspace iswspace +#define scisdigit iswdigit +#define scisprint iswprint +#define scisxdigit iswxdigit +#define scisalpha iswalpha +#define sciscntrl iswcntrl +#define scisalnum iswalnum + + +#define sq_rsl(l) ((l)<=0) + +#ifdef __GNUC__ +# define SQ_UNUSED_ARG(x) __attribute__((unused)) x +#else +# define SQ_UNUSED_ARG(x) x +#endif + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*_SQUIRREL_H_*/ diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/Makefile b/src/modules/app_sqlang/squirrel/sqstdlib/Makefile new file mode 100644 index 00000000000..62235a1f6c2 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/sqstdlib/Makefile @@ -0,0 +1,41 @@ +SQUIRREL= .. +LPATH ?= .. + +OUT= $(SQUIRREL)/$(LPATH)/libsqstdlib.a +INCZ= -I$(SQUIRREL)/include -I. -Iinclude + +OBJS= \ + sqstdblob.o \ + sqstdio.o \ + sqstdstream.o \ + sqstdmath.o \ + sqstdsystem.o \ + sqstdstring.o \ + sqstdaux.o \ + sqstdrex.o + +SRCS= \ + sqstdblob.cpp \ + sqstdio.cpp \ + sqstdstream.cpp \ + sqstdmath.cpp \ + sqstdsystem.cpp \ + sqstdstring.cpp \ + sqstdaux.cpp \ + sqstdrex.cpp + + +sq32: + gcc -O2 -fno-exceptions -fno-rtti -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) + ar rc $(OUT) *.o + rm *.o + +sqprof: + gcc -O2 -pg -fno-exceptions -fno-rtti -pie -gstabs -g3 -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) + ar rc $(OUT) *.o + rm *.o + +sq64: + gcc -O2 -m64 -fno-exceptions -D_SQ64 -fno-rtti -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) + ar rc $(OUT) *.o + rm *.o diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdaux.cpp b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdaux.cpp new file mode 100644 index 00000000000..3eac73df062 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdaux.cpp @@ -0,0 +1,130 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include + +void sqstd_printcallstack(HSQUIRRELVM 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")); + + 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(HSQUIRRELVM 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 OCCURED [%s]\n"),sErr); + } + else{ + pf(v,_SC("\nAN ERROR HAS OCCURED [unknown]\n")); + } + sqstd_printcallstack(v); + } + } + return 0; +} + +void _sqstd_compiler_error(HSQUIRRELVM 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); + } +} + +void sqstd_seterrorhandlers(HSQUIRRELVM v) +{ + sq_setcompilererrorhandler(v,_sqstd_compiler_error); + sq_newclosure(v,_sqstd_aux_printerror,0); + sq_seterrorhandler(v); +} diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdblob.cpp b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdblob.cpp new file mode 100644 index 00000000000..aaaaca417ac --- /dev/null +++ b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdblob.cpp @@ -0,0 +1,277 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include +#include "sqstdstream.h" +#include "sqstdblobimpl.h" + +#define SQSTD_BLOB_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000002) + +//Blob + + +#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")); + + +static SQInteger _blob_resize(HSQUIRRELVM v) +{ + 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)); +} + +static void __swap_word(unsigned short *n) +{ + *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00); +} + +static SQInteger _blob_swap4(HSQUIRRELVM 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; +} + +static SQInteger _blob_swap2(HSQUIRRELVM 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; +} + +static SQInteger _blob__set(HSQUIRRELVM 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; +} + +static SQInteger _blob__get(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger idx; + 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(HSQUIRRELVM 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")); +} + +static SQInteger _blob__typeof(HSQUIRRELVM v) +{ + 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; +} + +static SQInteger _blob_constructor(HSQUIRRELVM 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); + + 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(HSQUIRRELVM 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; +} + +#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("xn")), + _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} +}; + + + +//GLOBAL FUNCTIONS + +static SQInteger _g_blob_casti2f(HSQUIRRELVM v) +{ + SQInteger i; + sq_getinteger(v,2,&i); + sq_pushfloat(v,*((const SQFloat *)&i)); + return 1; +} + +static SQInteger _g_blob_castf2i(HSQUIRRELVM v) +{ + SQFloat f; + sq_getfloat(v,2,&f); + sq_pushinteger(v,*((const SQInteger *)&f)); + return 1; +} + +static SQInteger _g_blob_swap2(HSQUIRRELVM v) +{ + 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(HSQUIRRELVM v) +{ + 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(HSQUIRRELVM v) +{ + 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} +}; + +SQRESULT sqstd_getblob(HSQUIRRELVM 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; +} + +SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx) +{ + SQBlob *blob; + if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) + return -1; + return blob->Len(); +} + +SQUserPointer sqstd_createblob(HSQUIRRELVM 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; +} + +SQRESULT sqstd_register_bloblib(HSQUIRRELVM v) +{ + return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs); +} + diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdblobimpl.h b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdblobimpl.h new file mode 100644 index 00000000000..8f90eba879b --- /dev/null +++ b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdblobimpl.h @@ -0,0 +1,108 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_BLOBIMPL_H_ +#define _SQSTD_BLOBIMPL_H_ + +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 _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; +}; + +#endif //_SQSTD_BLOBIMPL_H_ diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdio.cpp b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdio.cpp new file mode 100644 index 00000000000..5bce4435469 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdio.cpp @@ -0,0 +1,485 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include "sqstdstream.h" + +#define SQSTD_FILE_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000001) +//basic API +SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode) +{ +#ifndef SQUNICODE + return (SQFILE)fopen(filename,mode); +#else + 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 sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE 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 sqstd_ftell(SQFILE file) +{ + return ftell((FILE *)file); +} + +SQInteger sqstd_fflush(SQFILE file) +{ + return fflush((FILE *)file); +} + +SQInteger sqstd_fclose(SQFILE file) +{ + return fclose((FILE *)file); +} + +SQInteger sqstd_feof(SQFILE 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;} +private: + SQFILE _handle; + bool _owns; +}; + +static SQInteger _file__typeof(HSQUIRRELVM v) +{ + 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; +} + +static SQInteger _file_constructor(HSQUIRRELVM 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")); + } + + 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(HSQUIRRELVM v) +{ + 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} +}; + + + +SQRESULT sqstd_createfile(HSQUIRRELVM 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; +} + +SQRESULT sqstd_getfile(HSQUIRRELVM 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")); +} + + + +#define IO_BUFFER_SIZE 2048 +struct IOBuffer { + unsigned char buffer[IO_BUFFER_SIZE]; + SQInteger size; + SQInteger ptr; + SQFILE file; +}; + +SQInteger _read_byte(IOBuffer *iobuffer) +{ + 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; + } + } + + 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; + } + } + + return 0; +} + +static SQInteger _io_file_lexfeed_PLAIN(SQUserPointer iobuf) +{ + IOBuffer *iobuffer = (IOBuffer *)iobuf; + return _read_byte(iobuffer); + +} + +#ifdef SQUNICODE +static SQInteger _io_file_lexfeed_UTF8(SQUserPointer iobuf) +{ + IOBuffer *iobuffer = (IOBuffer *)iobuf; +#define READ(iobuf) \ + 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; +} +#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; +} + +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 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 file_write(SQUserPointer file,SQUserPointer p,SQInteger size) +{ + return sqstd_fwrite(p,1,size,(SQFILE)file); +} + +SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror) +{ + 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 + + 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("Unrecognozed ecoding")); + } +#ifdef SQUNICODE + func = _io_file_lexfeed_UTF8; +#else + 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")); +} + +SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror) +{ + 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(HSQUIRRELVM 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 +} + +SQInteger _g_io_loadfile(HSQUIRRELVM 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 +} + +SQInteger _g_io_writeclosuretofile(HSQUIRRELVM v) +{ + 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(HSQUIRRELVM 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 +} + +#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} +}; + +SQRESULT sqstd_register_iolib(HSQUIRRELVM 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; +} diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdlib.dsp b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdlib.dsp new file mode 100644 index 00000000000..7453243fe8d --- /dev/null +++ b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdlib.dsp @@ -0,0 +1,131 @@ +# Microsoft Developer Studio Project File - Name="sqstdlib" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=sqstdlib - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "sqstdlib.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "sqstdlib.mak" CFG="sqstdlib - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "sqstdlib - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "sqstdlib - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_LocalPath ".." +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "sqstdlib - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "..\include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"..\lib\sqstdlib.lib" + +!ELSEIF "$(CFG)" == "sqstdlib - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"..\lib\sqstdlib.lib" + +!ENDIF + +# Begin Target + +# Name "sqstdlib - Win32 Release" +# Name "sqstdlib - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\sqstdblob.cpp +# End Source File +# Begin Source File + +SOURCE=.\sqstdio.cpp +# End Source File +# Begin Source File + +SOURCE=.\sqstdmath.cpp +# End Source File +# Begin Source File + +SOURCE=.\sqstdrex.cpp +# End Source File +# Begin Source File + +SOURCE=.\sqstdstream.cpp +# End Source File +# Begin Source File + +SOURCE=.\sqstdstring.cpp +# End Source File +# Begin Source File + +SOURCE=.\sqstdaux.cpp +# End Source File +# Begin Source File + +SOURCE=.\sqstdsystem.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\sqstdblobimpl.h +# End Source File +# Begin Source File + +SOURCE=.\sqstdstream.h +# End Source File +# End Group +# End Target +# End Project diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdmath.cpp b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdmath.cpp new file mode 100644 index 00000000000..492871d6b8e --- /dev/null +++ b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdmath.cpp @@ -0,0 +1,107 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include + +#define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \ + SQFloat f; \ + sq_getfloat(v,2,&f); \ + sq_pushfloat(v,(SQFloat)_funcname(f)); \ + return 1; \ +} + +#define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \ + 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(HSQUIRRELVM v) +{ + 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(HSQUIRRELVM v) +{ + sq_pushinteger(v,rand()); + return 1; +} + +static SQInteger math_abs(HSQUIRRELVM v) +{ + SQInteger n; + sq_getinteger(v,2,&n); + sq_pushinteger(v,(SQInteger)abs((int)n)); + return 1; +} + +SINGLE_ARG_FUNC(sqrt) +SINGLE_ARG_FUNC(fabs) +SINGLE_ARG_FUNC(sin) +SINGLE_ARG_FUNC(cos) +SINGLE_ARG_FUNC(asin) +SINGLE_ARG_FUNC(acos) +SINGLE_ARG_FUNC(log) +SINGLE_ARG_FUNC(log10) +SINGLE_ARG_FUNC(tan) +SINGLE_ARG_FUNC(atan) +TWO_ARGS_FUNC(atan2) +TWO_ARGS_FUNC(pow) +SINGLE_ARG_FUNC(floor) +SINGLE_ARG_FUNC(ceil) +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} +}; +#undef _DECL_FUNC + +#ifndef M_PI +#define M_PI (3.14159265358979323846) +#endif + +SQRESULT sqstd_register_mathlib(HSQUIRRELVM 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; +} diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdrex.cpp b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdrex.cpp new file mode 100644 index 00000000000..b4087911482 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdrex.cpp @@ -0,0 +1,663 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include + +#ifdef _DEBUG +#include + +static const SQChar *g_nnames[] = +{ + _SC("NONE"),_SC("OP_GREEDY"), _SC("OP_OR"), + _SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"), _SC("OP_CLASS"), + _SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"), + _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB"),_SC("OP_MB") +}; + +#endif + +#define OP_GREEDY (MAX_CHAR+1) // * + ? {n} +#define OP_OR (MAX_CHAR+2) +#define OP_EXPR (MAX_CHAR+3) //parentesis () +#define OP_NOCAPEXPR (MAX_CHAR+4) //parentesis (?:) +#define OP_DOT (MAX_CHAR+5) +#define OP_CLASS (MAX_CHAR+6) +#define OP_CCLASS (MAX_CHAR+7) +#define OP_NCLASS (MAX_CHAR+8) //negates class the [^ +#define OP_RANGE (MAX_CHAR+9) +#define OP_CHAR (MAX_CHAR+10) +#define OP_EOL (MAX_CHAR+11) +#define OP_BOL (MAX_CHAR+12) +#define OP_WB (MAX_CHAR+13) +#define OP_MB (MAX_CHAR+14) //match balanced + +#define SQREX_SYMBOL_ANY_CHAR ('.') +#define SQREX_SYMBOL_GREEDY_ONE_OR_MORE ('+') +#define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*') +#define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?') +#define SQREX_SYMBOL_BRANCH ('|') +#define SQREX_SYMBOL_END_OF_STRING ('$') +#define SQREX_SYMBOL_BEGINNING_OF_STRING ('^') +#define SQREX_SYMBOL_ESCAPE_CHAR ('\\') + + +typedef int SQRexNodeType; + +typedef struct tagSQRexNode{ + SQRexNodeType type; + SQInteger left; + SQInteger right; + SQInteger next; +}SQRexNode; + +struct SQRex{ + const SQChar *_eol; + const SQChar *_bol; + const SQChar *_p; + SQInteger _first; + SQInteger _op; + SQRexNode *_nodes; + SQInteger _nallocated; + SQInteger _nsize; + SQInteger _nsubexpr; + SQRexMatch *_matches; + SQInteger _currsubexp; + void *_jmpbuf; + const SQChar **_error; +}; + +static SQInteger sqstd_rex_list(SQRex *exp); + +static SQInteger sqstd_rex_newnode(SQRex *exp, SQRexNodeType type) +{ + SQRexNode n; + n.type = type; + n.next = n.right = n.left = -1; + if(type == OP_EXPR) + n.right = exp->_nsubexpr++; + if(exp->_nallocated < (exp->_nsize + 1)) { + SQInteger oldsize = exp->_nallocated; + exp->_nallocated *= 2; + exp->_nodes = (SQRexNode *)sq_realloc(exp->_nodes, oldsize * sizeof(SQRexNode) ,exp->_nallocated * sizeof(SQRexNode)); + } + exp->_nodes[exp->_nsize++] = n; + SQInteger newid = exp->_nsize - 1; + return (SQInteger)newid; +} + +static void sqstd_rex_error(SQRex *exp,const SQChar *error) +{ + if(exp->_error) *exp->_error = error; + longjmp(*((jmp_buf*)exp->_jmpbuf),-1); +} + +static void sqstd_rex_expect(SQRex *exp, SQInteger n){ + if((*exp->_p) != n) + sqstd_rex_error(exp, _SC("expected paren")); + exp->_p++; +} + +static SQChar sqstd_rex_escapechar(SQRex *exp) +{ + if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR){ + exp->_p++; + switch(*exp->_p) { + case 'v': exp->_p++; return '\v'; + case 'n': exp->_p++; return '\n'; + case 't': exp->_p++; return '\t'; + case 'r': exp->_p++; return '\r'; + case 'f': exp->_p++; return '\f'; + default: return (*exp->_p++); + } + } else if(!scisprint(*exp->_p)) sqstd_rex_error(exp,_SC("letter expected")); + return (*exp->_p++); +} + +static SQInteger sqstd_rex_charclass(SQRex *exp,SQInteger classid) +{ + SQInteger n = sqstd_rex_newnode(exp,OP_CCLASS); + exp->_nodes[n].left = classid; + return n; +} + +static SQInteger sqstd_rex_charnode(SQRex *exp,SQBool isclass) +{ + SQChar t; + if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR) { + exp->_p++; + switch(*exp->_p) { + case 'n': exp->_p++; return sqstd_rex_newnode(exp,'\n'); + case 't': exp->_p++; return sqstd_rex_newnode(exp,'\t'); + case 'r': exp->_p++; return sqstd_rex_newnode(exp,'\r'); + case 'f': exp->_p++; return sqstd_rex_newnode(exp,'\f'); + case 'v': exp->_p++; return sqstd_rex_newnode(exp,'\v'); + case 'a': case 'A': case 'w': case 'W': case 's': case 'S': + case 'd': case 'D': case 'x': case 'X': case 'c': case 'C': + case 'p': case 'P': case 'l': case 'u': + { + t = *exp->_p; exp->_p++; + return sqstd_rex_charclass(exp,t); + } + case 'm': + { + SQChar cb, ce; //cb = character begin match ce = character end match + cb = *++exp->_p; //skip 'm' + ce = *++exp->_p; + exp->_p++; //points to the next char to be parsed + if ((!cb) || (!ce)) sqstd_rex_error(exp,_SC("balanced chars expected")); + if ( cb == ce ) sqstd_rex_error(exp,_SC("open/close char can't be the same")); + SQInteger node = sqstd_rex_newnode(exp,OP_MB); + exp->_nodes[node].left = cb; + exp->_nodes[node].right = ce; + return node; + } + case 'b': + case 'B': + if(!isclass) { + SQInteger node = sqstd_rex_newnode(exp,OP_WB); + exp->_nodes[node].left = *exp->_p; + exp->_p++; + return node; + } //else default + default: + t = *exp->_p; exp->_p++; + return sqstd_rex_newnode(exp,t); + } + } + else if(!scisprint(*exp->_p)) { + + sqstd_rex_error(exp,_SC("letter expected")); + } + t = *exp->_p; exp->_p++; + return sqstd_rex_newnode(exp,t); +} +static SQInteger sqstd_rex_class(SQRex *exp) +{ + SQInteger ret = -1; + SQInteger first = -1,chain; + if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING){ + ret = sqstd_rex_newnode(exp,OP_NCLASS); + exp->_p++; + }else ret = sqstd_rex_newnode(exp,OP_CLASS); + + if(*exp->_p == ']') sqstd_rex_error(exp,_SC("empty class")); + chain = ret; + while(*exp->_p != ']' && exp->_p != exp->_eol) { + if(*exp->_p == '-' && first != -1){ + SQInteger r; + if(*exp->_p++ == ']') sqstd_rex_error(exp,_SC("unfinished range")); + r = sqstd_rex_newnode(exp,OP_RANGE); + if(exp->_nodes[first].type>*exp->_p) sqstd_rex_error(exp,_SC("invalid range")); + if(exp->_nodes[first].type == OP_CCLASS) sqstd_rex_error(exp,_SC("cannot use character classes in ranges")); + exp->_nodes[r].left = exp->_nodes[first].type; + SQInteger t = sqstd_rex_escapechar(exp); + exp->_nodes[r].right = t; + exp->_nodes[chain].next = r; + chain = r; + first = -1; + } + else{ + if(first!=-1){ + SQInteger c = first; + exp->_nodes[chain].next = c; + chain = c; + first = sqstd_rex_charnode(exp,SQTrue); + } + else{ + first = sqstd_rex_charnode(exp,SQTrue); + } + } + } + if(first!=-1){ + SQInteger c = first; + exp->_nodes[chain].next = c; + } + /* hack? */ + exp->_nodes[ret].left = exp->_nodes[ret].next; + exp->_nodes[ret].next = -1; + return ret; +} + +static SQInteger sqstd_rex_parsenumber(SQRex *exp) +{ + SQInteger ret = *exp->_p-'0'; + SQInteger positions = 10; + exp->_p++; + while(isdigit(*exp->_p)) { + ret = ret*10+(*exp->_p++-'0'); + if(positions==1000000000) sqstd_rex_error(exp,_SC("overflow in numeric constant")); + positions *= 10; + }; + return ret; +} + +static SQInteger sqstd_rex_element(SQRex *exp) +{ + SQInteger ret = -1; + switch(*exp->_p) + { + case '(': { + SQInteger expr; + exp->_p++; + + + if(*exp->_p =='?') { + exp->_p++; + sqstd_rex_expect(exp,':'); + expr = sqstd_rex_newnode(exp,OP_NOCAPEXPR); + } + else + expr = sqstd_rex_newnode(exp,OP_EXPR); + SQInteger newn = sqstd_rex_list(exp); + exp->_nodes[expr].left = newn; + ret = expr; + sqstd_rex_expect(exp,')'); + } + break; + case '[': + exp->_p++; + ret = sqstd_rex_class(exp); + sqstd_rex_expect(exp,']'); + break; + case SQREX_SYMBOL_END_OF_STRING: exp->_p++; ret = sqstd_rex_newnode(exp,OP_EOL);break; + case SQREX_SYMBOL_ANY_CHAR: exp->_p++; ret = sqstd_rex_newnode(exp,OP_DOT);break; + default: + ret = sqstd_rex_charnode(exp,SQFalse); + break; + } + + + SQBool isgreedy = SQFalse; + unsigned short p0 = 0, p1 = 0; + switch(*exp->_p){ + case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break; + case SQREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break; + case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; isgreedy = SQTrue; break; + case '{': + exp->_p++; + if(!isdigit(*exp->_p)) sqstd_rex_error(exp,_SC("number expected")); + p0 = (unsigned short)sqstd_rex_parsenumber(exp); + /*******************************/ + switch(*exp->_p) { + case '}': + p1 = p0; exp->_p++; + break; + case ',': + exp->_p++; + p1 = 0xFFFF; + if(isdigit(*exp->_p)){ + p1 = (unsigned short)sqstd_rex_parsenumber(exp); + } + sqstd_rex_expect(exp,'}'); + break; + default: + sqstd_rex_error(exp,_SC(", or } expected")); + } + /*******************************/ + isgreedy = SQTrue; + break; + + } + if(isgreedy) { + SQInteger nnode = sqstd_rex_newnode(exp,OP_GREEDY); + exp->_nodes[nnode].left = ret; + exp->_nodes[nnode].right = ((p0)<<16)|p1; + ret = nnode; + } + + if((*exp->_p != SQREX_SYMBOL_BRANCH) && (*exp->_p != ')') && (*exp->_p != SQREX_SYMBOL_GREEDY_ZERO_OR_MORE) && (*exp->_p != SQREX_SYMBOL_GREEDY_ONE_OR_MORE) && (*exp->_p != '\0')) { + SQInteger nnode = sqstd_rex_element(exp); + exp->_nodes[ret].next = nnode; + } + + return ret; +} + +static SQInteger sqstd_rex_list(SQRex *exp) +{ + SQInteger ret=-1,e; + if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING) { + exp->_p++; + ret = sqstd_rex_newnode(exp,OP_BOL); + } + e = sqstd_rex_element(exp); + if(ret != -1) { + exp->_nodes[ret].next = e; + } + else ret = e; + + if(*exp->_p == SQREX_SYMBOL_BRANCH) { + SQInteger temp,tright; + exp->_p++; + temp = sqstd_rex_newnode(exp,OP_OR); + exp->_nodes[temp].left = ret; + tright = sqstd_rex_list(exp); + exp->_nodes[temp].right = tright; + ret = temp; + } + return ret; +} + +static SQBool sqstd_rex_matchcclass(SQInteger cclass,SQChar c) +{ + switch(cclass) { + case 'a': return isalpha(c)?SQTrue:SQFalse; + case 'A': return !isalpha(c)?SQTrue:SQFalse; + case 'w': return (isalnum(c) || c == '_')?SQTrue:SQFalse; + case 'W': return (!isalnum(c) && c != '_')?SQTrue:SQFalse; + case 's': return isspace(c)?SQTrue:SQFalse; + case 'S': return !isspace(c)?SQTrue:SQFalse; + case 'd': return isdigit(c)?SQTrue:SQFalse; + case 'D': return !isdigit(c)?SQTrue:SQFalse; + case 'x': return isxdigit(c)?SQTrue:SQFalse; + case 'X': return !isxdigit(c)?SQTrue:SQFalse; + case 'c': return iscntrl(c)?SQTrue:SQFalse; + case 'C': return !iscntrl(c)?SQTrue:SQFalse; + case 'p': return ispunct(c)?SQTrue:SQFalse; + case 'P': return !ispunct(c)?SQTrue:SQFalse; + case 'l': return islower(c)?SQTrue:SQFalse; + case 'u': return isupper(c)?SQTrue:SQFalse; + } + return SQFalse; /*cannot happen*/ +} + +static SQBool sqstd_rex_matchclass(SQRex* exp,SQRexNode *node,SQChar c) +{ + do { + switch(node->type) { + case OP_RANGE: + if(c >= node->left && c <= node->right) return SQTrue; + break; + case OP_CCLASS: + if(sqstd_rex_matchcclass(node->left,c)) return SQTrue; + break; + default: + if(c == node->type)return SQTrue; + } + } while((node->next != -1) && (node = &exp->_nodes[node->next])); + return SQFalse; +} + +static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar *str,SQRexNode *next) +{ + + SQRexNodeType type = node->type; + switch(type) { + case OP_GREEDY: { + //SQRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL; + SQRexNode *greedystop = NULL; + SQInteger p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0; + const SQChar *s=str, *good = str; + + if(node->next != -1) { + greedystop = &exp->_nodes[node->next]; + } + else { + greedystop = next; + } + + while((nmaches == 0xFFFF || nmaches < p1)) { + + const SQChar *stop; + if(!(s = sqstd_rex_matchnode(exp,&exp->_nodes[node->left],s,greedystop))) + break; + nmaches++; + good=s; + if(greedystop) { + //checks that 0 matches satisfy the expression(if so skips) + //if not would always stop(for instance if is a '?') + if(greedystop->type != OP_GREEDY || + (greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0)) + { + SQRexNode *gnext = NULL; + if(greedystop->next != -1) { + gnext = &exp->_nodes[greedystop->next]; + }else if(next && next->next != -1){ + gnext = &exp->_nodes[next->next]; + } + stop = sqstd_rex_matchnode(exp,greedystop,s,gnext); + if(stop) { + //if satisfied stop it + if(p0 == p1 && p0 == nmaches) break; + else if(nmaches >= p0 && p1 == 0xFFFF) break; + else if(nmaches >= p0 && nmaches <= p1) break; + } + } + } + + if(s >= exp->_eol) + break; + } + if(p0 == p1 && p0 == nmaches) return good; + else if(nmaches >= p0 && p1 == 0xFFFF) return good; + else if(nmaches >= p0 && nmaches <= p1) return good; + return NULL; + } + case OP_OR: { + const SQChar *asd = str; + SQRexNode *temp=&exp->_nodes[node->left]; + while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) { + if(temp->next != -1) + temp = &exp->_nodes[temp->next]; + else + return asd; + } + asd = str; + temp = &exp->_nodes[node->right]; + while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) { + if(temp->next != -1) + temp = &exp->_nodes[temp->next]; + else + return asd; + } + return NULL; + break; + } + case OP_EXPR: + case OP_NOCAPEXPR:{ + SQRexNode *n = &exp->_nodes[node->left]; + const SQChar *cur = str; + SQInteger capture = -1; + if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) { + capture = exp->_currsubexp; + exp->_matches[capture].begin = cur; + exp->_currsubexp++; + } + SQInteger tempcap = exp->_currsubexp; + do { + SQRexNode *subnext = NULL; + if(n->next != -1) { + subnext = &exp->_nodes[n->next]; + }else { + subnext = next; + } + if(!(cur = sqstd_rex_matchnode(exp,n,cur,subnext))) { + if(capture != -1){ + exp->_matches[capture].begin = 0; + exp->_matches[capture].len = 0; + } + return NULL; + } + } while((n->next != -1) && (n = &exp->_nodes[n->next])); + + exp->_currsubexp = tempcap; + if(capture != -1) + exp->_matches[capture].len = cur - exp->_matches[capture].begin; + return cur; + } + case OP_WB: + if((str == exp->_bol && !isspace(*str)) + || (str == exp->_eol && !isspace(*(str-1))) + || (!isspace(*str) && isspace(*(str+1))) + || (isspace(*str) && !isspace(*(str+1))) ) { + return (node->left == 'b')?str:NULL; + } + return (node->left == 'b')?NULL:str; + case OP_BOL: + if(str == exp->_bol) return str; + return NULL; + case OP_EOL: + if(str == exp->_eol) return str; + return NULL; + case OP_DOT:{ + if (str == exp->_eol) return NULL; + str++; + } + return str; + case OP_NCLASS: + case OP_CLASS: + if (str == exp->_eol) return NULL; + if(sqstd_rex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?SQTrue:SQFalse):(type == OP_NCLASS?SQTrue:SQFalse)) { + str++; + return str; + } + return NULL; + case OP_CCLASS: + if (str == exp->_eol) return NULL; + if(sqstd_rex_matchcclass(node->left,*str)) { + str++; + return str; + } + return NULL; + case OP_MB: + { + SQInteger cb = node->left; //char that opens a balanced expression + if(*str != cb) return NULL; // string doesnt start with open char + SQInteger ce = node->right; //char that closes a balanced expression + SQInteger cont = 1; + const SQChar *streol = exp->_eol; + while (++str < streol) { + if (*str == ce) { + if (--cont == 0) { + return ++str; + } + } + else if (*str == cb) cont++; + } + } + return NULL; // string ends out of balance + default: /* char */ + if (str == exp->_eol) return NULL; + if(*str != node->type) return NULL; + str++; + return str; + } + return NULL; +} + +/* public api */ +SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error) +{ + SQRex * volatile exp = (SQRex *)sq_malloc(sizeof(SQRex)); // "volatile" is needed for setjmp() + exp->_eol = exp->_bol = NULL; + exp->_p = pattern; + exp->_nallocated = (SQInteger)scstrlen(pattern) * sizeof(SQChar); + exp->_nodes = (SQRexNode *)sq_malloc(exp->_nallocated * sizeof(SQRexNode)); + exp->_nsize = 0; + exp->_matches = 0; + exp->_nsubexpr = 0; + exp->_first = sqstd_rex_newnode(exp,OP_EXPR); + exp->_error = error; + exp->_jmpbuf = sq_malloc(sizeof(jmp_buf)); + if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) { + SQInteger res = sqstd_rex_list(exp); + exp->_nodes[exp->_first].left = res; + if(*exp->_p!='\0') + sqstd_rex_error(exp,_SC("unexpected character")); +#ifdef _DEBUG + { + SQInteger nsize,i; + SQRexNode *t; + nsize = exp->_nsize; + t = &exp->_nodes[0]; + scprintf(_SC("\n")); + for(i = 0;i < nsize; i++) { + if(exp->_nodes[i].type>MAX_CHAR) + scprintf(_SC("[%02d] %10s "),i,g_nnames[exp->_nodes[i].type-MAX_CHAR]); + else + scprintf(_SC("[%02d] %10c "),i,exp->_nodes[i].type); + scprintf(_SC("left %02d right %02d next %02d\n"), (SQInt32)exp->_nodes[i].left, (SQInt32)exp->_nodes[i].right, (SQInt32)exp->_nodes[i].next); + } + scprintf(_SC("\n")); + } +#endif + exp->_matches = (SQRexMatch *) sq_malloc(exp->_nsubexpr * sizeof(SQRexMatch)); + memset(exp->_matches,0,exp->_nsubexpr * sizeof(SQRexMatch)); + } + else{ + sqstd_rex_free(exp); + return NULL; + } + return exp; +} + +void sqstd_rex_free(SQRex *exp) +{ + if(exp) { + if(exp->_nodes) sq_free(exp->_nodes,exp->_nallocated * sizeof(SQRexNode)); + if(exp->_jmpbuf) sq_free(exp->_jmpbuf,sizeof(jmp_buf)); + if(exp->_matches) sq_free(exp->_matches,exp->_nsubexpr * sizeof(SQRexMatch)); + sq_free(exp,sizeof(SQRex)); + } +} + +SQBool sqstd_rex_match(SQRex* exp,const SQChar* text) +{ + const SQChar* res = NULL; + exp->_bol = text; + exp->_eol = text + scstrlen(text); + exp->_currsubexp = 0; + res = sqstd_rex_matchnode(exp,exp->_nodes,text,NULL); + if(res == NULL || res != exp->_eol) + return SQFalse; + return SQTrue; +} + +SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end) +{ + const SQChar *cur = NULL; + SQInteger node = exp->_first; + if(text_begin >= text_end) return SQFalse; + exp->_bol = text_begin; + exp->_eol = text_end; + do { + cur = text_begin; + while(node != -1) { + exp->_currsubexp = 0; + cur = sqstd_rex_matchnode(exp,&exp->_nodes[node],cur,NULL); + if(!cur) + break; + node = exp->_nodes[node].next; + } + text_begin++; + } while(cur == NULL && text_begin != text_end); + + if(cur == NULL) + return SQFalse; + + --text_begin; + + if(out_begin) *out_begin = text_begin; + if(out_end) *out_end = cur; + return SQTrue; +} + +SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end) +{ + return sqstd_rex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end); +} + +SQInteger sqstd_rex_getsubexpcount(SQRex* exp) +{ + return exp->_nsubexpr; +} + +SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp) +{ + if( n<0 || n >= exp->_nsubexpr) return SQFalse; + *subexp = exp->_matches[n]; + return SQTrue; +} + diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstream.cpp b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstream.cpp new file mode 100644 index 00000000000..d47f5169602 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstream.cpp @@ -0,0 +1,336 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include +#include +#include +#include "sqstdstream.h" +#include "sqstdblobimpl.h" + +#define SETUP_STREAM(v) \ + SQStream *self = NULL; \ + if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)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(HSQUIRRELVM 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; +} + +#define SAFE_READN(ptr,len) { \ + if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \ + } +SQInteger _stream_readn(HSQUIRRELVM 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; +} + +SQInteger _stream_writeblob(HSQUIRRELVM 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; +} + +SQInteger _stream_writen(HSQUIRRELVM 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; +} + +SQInteger _stream_seek(HSQUIRRELVM 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; +} + +SQInteger _stream_tell(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + sq_pushinteger(v, self->Tell()); + return 1; +} + +SQInteger _stream_len(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + sq_pushinteger(v, self->Len()); + return 1; +} + +SQInteger _stream_flush(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + if(!self->Flush()) + sq_pushinteger(v, 1); + else + sq_pushnull(v); + return 1; +} + +SQInteger _stream_eos(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + if(self->EOS()) + sq_pushinteger(v, 1); + else + sq_pushnull(v); + return 1; +} + + SQInteger _stream__cloned(HSQUIRRELVM v) + { + 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} +}; + +void init_streamclass(HSQUIRRELVM 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)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(HSQUIRRELVM 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); + + 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; +} diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstream.h b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstream.h new file mode 100644 index 00000000000..436c18c9ac4 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstream.h @@ -0,0 +1,18 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_STREAM_H_ +#define _SQSTD_STREAM_H_ + +SQInteger _stream_readblob(HSQUIRRELVM v); +SQInteger _stream_readline(HSQUIRRELVM v); +SQInteger _stream_readn(HSQUIRRELVM v); +SQInteger _stream_writeblob(HSQUIRRELVM v); +SQInteger _stream_writen(HSQUIRRELVM v); +SQInteger _stream_seek(HSQUIRRELVM v); +SQInteger _stream_tell(HSQUIRRELVM v); +SQInteger _stream_len(HSQUIRRELVM v); +SQInteger _stream_eos(HSQUIRRELVM v); +SQInteger _stream_flush(HSQUIRRELVM v); + +#define _DECL_STREAM_FUNC(name,nparams,typecheck) {_SC(#name),_stream_##name,nparams,typecheck} +SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,const SQRegFunction *methods,const SQRegFunction *globals); +#endif /*_SQSTD_STREAM_H_*/ diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstring.cpp b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstring.cpp new file mode 100644 index 00000000000..a22a629b63d --- /dev/null +++ b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstring.cpp @@ -0,0 +1,501 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include +#include +#include + +#define MAX_FORMAT_LEN 20 +#define MAX_WFORMAT_LEN 3 +#define ADDITIONAL_FORMAT_SPACE (100*sizeof(SQChar)) + +static SQBool isfmtchr(SQChar ch) +{ + switch(ch) { + case '-': case '+': case ' ': case '#': case '0': return SQTrue; + } + return SQFalse; +} + +static SQInteger validate_format(HSQUIRRELVM 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++; + + 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; +} + +SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output) +{ + const SQChar *format; + SQChar *dest; + SQChar fmt[MAX_FORMAT_LEN]; + sq_getstring(v,nformatstringidx,&format); + 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 paramters 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'); + } +#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; +} + +static SQInteger _string_format(HSQUIRRELVM 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; +} + +static void __strip_l(const SQChar *str,const SQChar **start) +{ + 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; +} + +static SQInteger _string_strip(HSQUIRRELVM 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; +} + +static SQInteger _string_lstrip(HSQUIRRELVM v) +{ + const SQChar *str,*start; + sq_getstring(v,2,&str); + __strip_l(str,&start); + sq_pushstring(v,start,-1); + return 1; +} + +static SQInteger _string_rstrip(HSQUIRRELVM 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; +} + +static SQInteger _string_split(HSQUIRRELVM 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; +} + +static SQInteger _string_escape(HSQUIRRELVM 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; + } +#ifdef SQUNICODE +#if WCHAR_SIZE == 2 + const SQChar *escpat = _SC("\\x%04x"); + const SQInteger maxescsize = 6; +#else //WCHAR_SIZE == 4 + const SQChar *escpat = _SC("\\x%08x"); + const SQInteger maxescsize = 10; +#endif +#else + 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 { + + dest += scsprintf(dest, destcharsize, escpat, c); + escaped++; + } + } + + if(escaped) { + sq_pushstring(v,resstr,dest - resstr); + } + else { + sq_push(v,2); //nothing escaped + } + return 1; +} + +static SQInteger _string_startswith(HSQUIRRELVM 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; +} + +static SQInteger _string_endswith(HSQUIRRELVM 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; +} + +#define SETUP_REX(v) \ + 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; +} + +static SQInteger _regexp_match(HSQUIRRELVM 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; +} + +static void _addrexmatch(HSQUIRRELVM 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); +} + +static SQInteger _regexp_search(HSQUIRRELVM 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; +} + +static SQInteger _regexp_capture(HSQUIRRELVM 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; +} + +static SQInteger _regexp_subexpcount(HSQUIRRELVM v) +{ + SETUP_REX(v); + sq_pushinteger(v,sqstd_rex_getsubexpcount(self)); + return 1; +} + +static SQInteger _regexp_constructor(HSQUIRRELVM 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; +} + +static SQInteger _regexp__typeof(HSQUIRRELVM v) +{ + 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} +}; +#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(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(HSQUIRRELVM 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); + + 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; +} diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdsystem.cpp b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdsystem.cpp new file mode 100644 index 00000000000..c34a2484487 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdsystem.cpp @@ -0,0 +1,146 @@ +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include + +#ifdef SQUNICODE +#include +#define scgetenv _wgetenv +#define scsystem _wsystem +#define scasctime _wasctime +#define scremove _wremove +#define screname _wrename +#else +#define scgetenv getenv +#define scsystem system +#define scasctime asctime +#define scremove remove +#define screname rename +#endif + +static SQInteger _system_getenv(HSQUIRRELVM v) +{ + 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(HSQUIRRELVM 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")); +} + + +static SQInteger _system_clock(HSQUIRRELVM v) +{ + sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC); + return 1; +} + +static SQInteger _system_time(HSQUIRRELVM v) +{ + SQInteger t = (SQInteger)time(NULL); + sq_pushinteger(v,t); + return 1; +} + +static SQInteger _system_remove(HSQUIRRELVM v) +{ + 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(HSQUIRRELVM 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; +} + +static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val) +{ + sq_pushstring(v,name,-1); + sq_pushinteger(v,val); + sq_rawset(v,-3); +} + +static SQInteger _system_date(HSQUIRRELVM 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; +} + + + +#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} +}; +#undef _DECL_FUNC + +SQInteger sqstd_register_systemlib(HSQUIRRELVM 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; +} diff --git a/src/modules/app_sqlang/squirrel/squirrel/Makefile b/src/modules/app_sqlang/squirrel/squirrel/Makefile new file mode 100644 index 00000000000..379b95d2898 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/Makefile @@ -0,0 +1,52 @@ +SQUIRREL= .. +LPATH ?= .. + +OUT= $(SQUIRREL)/$(LPATH)/libsquirrel.a +INCZ= -I$(SQUIRREL)/include -I. -Iinclude +DEFS= +LIB= + +OBJS= \ + sqapi.o \ + sqbaselib.o \ + sqfuncstate.o \ + sqdebug.o \ + sqlexer.o \ + sqobject.o \ + sqcompiler.o \ + sqstate.o \ + sqtable.o \ + sqmem.o \ + sqvm.o \ + sqclass.o + +SRCS= \ + sqapi.cpp \ + sqbaselib.cpp \ + sqfuncstate.cpp \ + sqdebug.cpp \ + sqlexer.cpp \ + sqobject.cpp \ + sqcompiler.cpp \ + sqstate.cpp \ + sqtable.cpp \ + sqmem.cpp \ + sqvm.cpp \ + sqclass.cpp + + + +sq32: + gcc -O2 -fno-exceptions -fno-rtti -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS) + ar rc $(OUT) *.o + rm *.o + +sqprof: + gcc -O2 -pg -fno-exceptions -fno-rtti -pie -gstabs -g3 -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS) + ar rc $(OUT) *.o + rm *.o + +sq64: + gcc -O2 -m64 -D_SQ64 -fno-exceptions -fno-rtti -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS) + ar rc $(OUT) *.o + rm *.o diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqapi.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqapi.cpp new file mode 100644 index 00000000000..2005e327427 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqapi.cpp @@ -0,0 +1,1602 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqstring.h" +#include "sqtable.h" +#include "sqarray.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "squserdata.h" +#include "sqcompiler.h" +#include "sqfuncstate.h" +#include "sqclass.h" + +static bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPtr **o) +{ + *o = &stack_get(v,idx); + if(type(**o) != type){ + SQObjectPtr oval = v->PrintObjVal(**o); + v->Raise_Error(_SC("wrong argument type, expected '%s' got '%.50s'"),IdType2Name(type),_stringval(oval)); + return false; + } + return true; +} + +#define _GETSAFE_OBJ(v,idx,type,o) { if(!sq_aux_gettypedarg(v,idx,type,&o)) return SQ_ERROR; } + +#define sq_aux_paramscheck(v,count) \ +{ \ + if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\ +} + + +SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type) +{ + SQUnsignedInteger buf_size = 100 *sizeof(SQChar); + scsprintf(_ss(v)->GetScratchPad(buf_size), buf_size, _SC("unexpected type %s"), IdType2Name(type)); + return sq_throwerror(v, _ss(v)->GetScratchPad(-1)); +} + +HSQUIRRELVM sq_open(SQInteger initialstacksize) +{ + SQSharedState *ss; + SQVM *v; + sq_new(ss, SQSharedState); + ss->Init(); + v = (SQVM *)SQ_MALLOC(sizeof(SQVM)); + new (v) SQVM(ss); + ss->_root_vm = v; + if(v->Init(NULL, initialstacksize)) { + return v; + } else { + sq_delete(v, SQVM); + return NULL; + } + return v; +} + +HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize) +{ + SQSharedState *ss; + SQVM *v; + ss=_ss(friendvm); + + v= (SQVM *)SQ_MALLOC(sizeof(SQVM)); + new (v) SQVM(ss); + + if(v->Init(friendvm, initialstacksize)) { + friendvm->Push(v); + return v; + } else { + sq_delete(v, SQVM); + return NULL; + } +} + +SQInteger sq_getvmstate(HSQUIRRELVM v) +{ + if(v->_suspended) + return SQ_VMSTATE_SUSPENDED; + else { + if(v->_callsstacksize != 0) return SQ_VMSTATE_RUNNING; + else return SQ_VMSTATE_IDLE; + } +} + +void sq_seterrorhandler(HSQUIRRELVM v) +{ + SQObject o = stack_get(v, -1); + if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) { + v->_errorhandler = o; + v->Pop(); + } +} + +void sq_setnativedebughook(HSQUIRRELVM v,SQDEBUGHOOK hook) +{ + v->_debughook_native = hook; + v->_debughook_closure.Null(); + v->_debughook = hook?true:false; +} + +void sq_setdebughook(HSQUIRRELVM v) +{ + SQObject o = stack_get(v,-1); + if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) { + v->_debughook_closure = o; + v->_debughook_native = NULL; + v->_debughook = !sq_isnull(o); + v->Pop(); + } +} + +void sq_close(HSQUIRRELVM v) +{ + SQSharedState *ss = _ss(v); + _thread(ss->_root_vm)->Finalize(); + sq_delete(ss, SQSharedState); +} + +SQInteger sq_getversion() +{ + return SQUIRREL_VERSION_NUMBER; +} + +SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror) +{ + SQObjectPtr o; +#ifndef NO_COMPILER + if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) { + v->Push(SQClosure::Create(_ss(v), _funcproto(o), _table(v->_roottable)->GetWeakRef(OT_TABLE))); + return SQ_OK; + } + return SQ_ERROR; +#else + return sq_throwerror(v,_SC("this is a no compiler build")); +#endif +} + +void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable) +{ + _ss(v)->_debuginfo = enable?true:false; +} + +void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable) +{ + _ss(v)->_notifyallexceptions = enable?true:false; +} + +void sq_addref(HSQUIRRELVM v,HSQOBJECT *po) +{ + if(!ISREFCOUNTED(type(*po))) return; +#ifdef NO_GARBAGE_COLLECTOR + __AddRef(po->_type,po->_unVal); +#else + _ss(v)->_refs_table.AddRef(*po); +#endif +} + +SQUnsignedInteger sq_getrefcount(HSQUIRRELVM v,HSQOBJECT *po) +{ + if(!ISREFCOUNTED(type(*po))) return 0; +#ifdef NO_GARBAGE_COLLECTOR + return po->_unVal.pRefCounted->_uiRef; +#else + return _ss(v)->_refs_table.GetRefCount(*po); +#endif +} + +SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po) +{ + if(!ISREFCOUNTED(type(*po))) return SQTrue; +#ifdef NO_GARBAGE_COLLECTOR + bool ret = (po->_unVal.pRefCounted->_uiRef <= 1) ? SQTrue : SQFalse; + __Release(po->_type,po->_unVal); + return ret; //the ret val doesn't work(and cannot be fixed) +#else + return _ss(v)->_refs_table.Release(*po); +#endif +} + +SQUnsignedInteger sq_getvmrefcount(HSQUIRRELVM SQ_UNUSED_ARG(v), const HSQOBJECT *po) +{ + if (!ISREFCOUNTED(type(*po))) return 0; + return po->_unVal.pRefCounted->_uiRef; +} + +const SQChar *sq_objtostring(const HSQOBJECT *o) +{ + if(sq_type(*o) == OT_STRING) { + return _stringval(*o); + } + return NULL; +} + +SQInteger sq_objtointeger(const HSQOBJECT *o) +{ + if(sq_isnumeric(*o)) { + return tointeger(*o); + } + return 0; +} + +SQFloat sq_objtofloat(const HSQOBJECT *o) +{ + if(sq_isnumeric(*o)) { + return tofloat(*o); + } + return 0; +} + +SQBool sq_objtobool(const HSQOBJECT *o) +{ + if(sq_isbool(*o)) { + return _integer(*o); + } + return SQFalse; +} + +SQUserPointer sq_objtouserpointer(const HSQOBJECT *o) +{ + if(sq_isuserpointer(*o)) { + return _userpointer(*o); + } + return 0; +} + +void sq_pushnull(HSQUIRRELVM v) +{ + v->PushNull(); +} + +void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len) +{ + if(s) + v->Push(SQObjectPtr(SQString::Create(_ss(v), s, len))); + else v->PushNull(); +} + +void sq_pushinteger(HSQUIRRELVM v,SQInteger n) +{ + v->Push(n); +} + +void sq_pushbool(HSQUIRRELVM v,SQBool b) +{ + v->Push(b?true:false); +} + +void sq_pushfloat(HSQUIRRELVM v,SQFloat n) +{ + v->Push(n); +} + +void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p) +{ + v->Push(p); +} + +void sq_pushthread(HSQUIRRELVM v, HSQUIRRELVM thread) +{ + v->Push(thread); +} + +SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size) +{ + SQUserData *ud = SQUserData::Create(_ss(v), size + SQ_ALIGNMENT); + v->Push(ud); + return (SQUserPointer)sq_aligning(ud + 1); +} + +void sq_newtable(HSQUIRRELVM v) +{ + v->Push(SQTable::Create(_ss(v), 0)); +} + +void sq_newtableex(HSQUIRRELVM v,SQInteger initialcapacity) +{ + v->Push(SQTable::Create(_ss(v), initialcapacity)); +} + +void sq_newarray(HSQUIRRELVM v,SQInteger size) +{ + v->Push(SQArray::Create(_ss(v), size)); +} + +SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase) +{ + SQClass *baseclass = NULL; + if(hasbase) { + SQObjectPtr &base = stack_get(v,-1); + if(type(base) != OT_CLASS) + return sq_throwerror(v,_SC("invalid base type")); + baseclass = _class(base); + } + SQClass *newclass = SQClass::Create(_ss(v), baseclass); + if(baseclass) v->Pop(); + v->Push(newclass); + return SQ_OK; +} + +SQBool sq_instanceof(HSQUIRRELVM v) +{ + SQObjectPtr &inst = stack_get(v,-1); + SQObjectPtr &cl = stack_get(v,-2); + if(type(inst) != OT_INSTANCE || type(cl) != OT_CLASS) + return sq_throwerror(v,_SC("invalid param type")); + return _instance(inst)->InstanceOf(_class(cl))?SQTrue:SQFalse; +} + +SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx) +{ + sq_aux_paramscheck(v,2); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + _array(*arr)->Append(v->GetUp(-1)); + v->Pop(); + return SQ_OK; +} + +SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + if(_array(*arr)->Size() > 0) { + if(pushval != 0){ v->Push(_array(*arr)->Top()); } + _array(*arr)->Pop(); + return SQ_OK; + } + return sq_throwerror(v, _SC("empty array")); +} + +SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize) +{ + sq_aux_paramscheck(v,1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + if(newsize >= 0) { + _array(*arr)->Resize(newsize); + return SQ_OK; + } + return sq_throwerror(v,_SC("negative size")); +} + + +SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *o; + _GETSAFE_OBJ(v, idx, OT_ARRAY,o); + SQArray *arr = _array(*o); + if(arr->Size() > 0) { + SQObjectPtr t; + SQInteger size = arr->Size(); + SQInteger n = size >> 1; size -= 1; + for(SQInteger i = 0; i < n; i++) { + t = arr->_values[i]; + arr->_values[i] = arr->_values[size-i]; + arr->_values[size-i] = t; + } + return SQ_OK; + } + return SQ_OK; +} + +SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + return _array(*arr)->Remove(itemidx) ? SQ_OK : sq_throwerror(v,_SC("index out of range")); +} + +SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + SQRESULT ret = _array(*arr)->Insert(destpos, v->GetUp(-1)) ? SQ_OK : sq_throwerror(v,_SC("index out of range")); + v->Pop(); + return ret; +} + +void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars) +{ + SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func,nfreevars); + nc->_nparamscheck = 0; + for(SQUnsignedInteger i = 0; i < nfreevars; i++) { + nc->_outervalues[i] = v->Top(); + v->Pop(); + } + v->Push(SQObjectPtr(nc)); +} + +SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars) +{ + SQObject o = stack_get(v, idx); + if(type(o) == OT_CLOSURE) { + SQClosure *c = _closure(o); + SQFunctionProto *proto = c->_function; + *nparams = (SQUnsignedInteger)proto->_nparameters; + *nfreevars = (SQUnsignedInteger)proto->_noutervalues; + return SQ_OK; + } + else if(type(o) == OT_NATIVECLOSURE) + { + SQNativeClosure *c = _nativeclosure(o); + *nparams = (SQUnsignedInteger)c->_nparamscheck; + *nfreevars = c->_noutervalues; + return SQ_OK; + } + return sq_throwerror(v,_SC("the object is not a closure")); +} + +SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name) +{ + SQObject o = stack_get(v, idx); + if(sq_isnativeclosure(o)) { + SQNativeClosure *nc = _nativeclosure(o); + nc->_name = SQString::Create(_ss(v),name); + return SQ_OK; + } + return sq_throwerror(v,_SC("the object is not a nativeclosure")); +} + +SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask) +{ + SQObject o = stack_get(v, -1); + if(!sq_isnativeclosure(o)) + return sq_throwerror(v, _SC("native closure expected")); + SQNativeClosure *nc = _nativeclosure(o); + nc->_nparamscheck = nparamscheck; + if(typemask) { + SQIntVec res; + if(!CompileTypemask(res, typemask)) + return sq_throwerror(v, _SC("invalid typemask")); + nc->_typecheck.copy(res); + } + else { + nc->_typecheck.resize(0); + } + if(nparamscheck == SQ_MATCHTYPEMASKSTRING) { + nc->_nparamscheck = nc->_typecheck.size(); + } + return SQ_OK; +} + +SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v,idx); + if(!sq_isnativeclosure(o) && + !sq_isclosure(o)) + return sq_throwerror(v,_SC("the target is not a closure")); + SQObjectPtr &env = stack_get(v,-1); + if(!sq_istable(env) && + !sq_isarray(env) && + !sq_isclass(env) && + !sq_isinstance(env)) + return sq_throwerror(v,_SC("invalid environment")); + SQWeakRef *w = _refcounted(env)->GetWeakRef(type(env)); + SQObjectPtr ret; + if(sq_isclosure(o)) { + SQClosure *c = _closure(o)->Clone(); + __ObjRelease(c->_env); + c->_env = w; + __ObjAddRef(c->_env); + if(_closure(o)->_base) { + c->_base = _closure(o)->_base; + __ObjAddRef(c->_base); + } + ret = c; + } + else { //then must be a native closure + SQNativeClosure *c = _nativeclosure(o)->Clone(); + __ObjRelease(c->_env); + c->_env = w; + __ObjAddRef(c->_env); + ret = c; + } + v->Pop(); + v->Push(ret); + return SQ_OK; +} + +SQRESULT sq_getclosurename(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v,idx); + if(!sq_isnativeclosure(o) && + !sq_isclosure(o)) + return sq_throwerror(v,_SC("the target is not a closure")); + if(sq_isnativeclosure(o)) + { + v->Push(_nativeclosure(o)->_name); + } + else { //closure + v->Push(_closure(o)->_function->_name); + } + return SQ_OK; +} + +SQRESULT sq_setclosureroot(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &c = stack_get(v,idx); + SQObject o = stack_get(v, -1); + if(!sq_isclosure(c)) return sq_throwerror(v, _SC("closure expected")); + if(sq_istable(o)) { + _closure(c)->SetRoot(_table(o)->GetWeakRef(OT_TABLE)); + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v, _SC("ivalid type")); +} + +SQRESULT sq_getclosureroot(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &c = stack_get(v,idx); + if(!sq_isclosure(c)) return sq_throwerror(v, _SC("closure expected")); + v->Push(_closure(c)->_root->_obj); + return SQ_OK; +} + +SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx) +{ + SQObject &o=stack_get(v,idx); + switch(type(o)) { + case OT_TABLE: _table(o)->Clear(); break; + case OT_ARRAY: _array(o)->Resize(0); break; + default: + return sq_throwerror(v, _SC("clear only works on table and array")); + break; + + } + return SQ_OK; +} + +void sq_pushroottable(HSQUIRRELVM v) +{ + v->Push(v->_roottable); +} + +void sq_pushregistrytable(HSQUIRRELVM v) +{ + v->Push(_ss(v)->_registry); +} + +void sq_pushconsttable(HSQUIRRELVM v) +{ + v->Push(_ss(v)->_consts); +} + +SQRESULT sq_setroottable(HSQUIRRELVM v) +{ + SQObject o = stack_get(v, -1); + if(sq_istable(o) || sq_isnull(o)) { + v->_roottable = o; + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v, _SC("ivalid type")); +} + +SQRESULT sq_setconsttable(HSQUIRRELVM v) +{ + SQObject o = stack_get(v, -1); + if(sq_istable(o)) { + _ss(v)->_consts = o; + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v, _SC("ivalid type, expected table")); +} + +void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p) +{ + v->_foreignptr = p; +} + +SQUserPointer sq_getforeignptr(HSQUIRRELVM v) +{ + return v->_foreignptr; +} + +void sq_setsharedforeignptr(HSQUIRRELVM v,SQUserPointer p) +{ + _ss(v)->_foreignptr = p; +} + +SQUserPointer sq_getsharedforeignptr(HSQUIRRELVM v) +{ + return _ss(v)->_foreignptr; +} + +void sq_setvmreleasehook(HSQUIRRELVM v,SQRELEASEHOOK hook) +{ + v->_releasehook = hook; +} + +SQRELEASEHOOK sq_getvmreleasehook(HSQUIRRELVM v) +{ + return v->_releasehook; +} + +void sq_setsharedreleasehook(HSQUIRRELVM v,SQRELEASEHOOK hook) +{ + _ss(v)->_releasehook = hook; +} + +SQRELEASEHOOK sq_getsharedreleasehook(HSQUIRRELVM v) +{ + return _ss(v)->_releasehook; +} + +void sq_push(HSQUIRRELVM v,SQInteger idx) +{ + v->Push(stack_get(v, idx)); +} + +SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx) +{ + return type(stack_get(v, idx)); +} + +SQRESULT sq_typeof(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v, idx); + SQObjectPtr res; + if(!v->TypeOf(o,res)) { + return SQ_ERROR; + } + v->Push(res); + return SQ_OK; +} + +SQRESULT sq_tostring(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v, idx); + SQObjectPtr res; + if(!v->ToString(o,res)) { + return SQ_ERROR; + } + v->Push(res); + return SQ_OK; +} + +void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b) +{ + SQObjectPtr &o = stack_get(v, idx); + *b = SQVM::IsFalse(o)?SQFalse:SQTrue; +} + +SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i) +{ + SQObjectPtr &o = stack_get(v, idx); + if(sq_isnumeric(o)) { + *i = tointeger(o); + return SQ_OK; + } + return SQ_ERROR; +} + +SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f) +{ + SQObjectPtr &o = stack_get(v, idx); + if(sq_isnumeric(o)) { + *f = tofloat(o); + return SQ_OK; + } + return SQ_ERROR; +} + +SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b) +{ + SQObjectPtr &o = stack_get(v, idx); + if(sq_isbool(o)) { + *b = _integer(o); + return SQ_OK; + } + return SQ_ERROR; +} + +SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_STRING,o); + *c = _stringval(*o); + return SQ_OK; +} + +SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_THREAD,o); + *thread = _thread(*o); + return SQ_OK; +} + +SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v,idx); + v->PushNull(); + if(!v->Clone(o, stack_get(v, -1))){ + v->Pop(); + return SQ_ERROR; + } + return SQ_OK; +} + +SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx) +{ + SQObjectPtr &o = stack_get(v, idx); + SQObjectType type = type(o); + switch(type) { + case OT_STRING: return _string(o)->_len; + case OT_TABLE: return _table(o)->CountUsed(); + case OT_ARRAY: return _array(o)->Size(); + case OT_USERDATA: return _userdata(o)->_size; + case OT_INSTANCE: return _instance(o)->_class->_udsize; + case OT_CLASS: return _class(o)->_udsize; + default: + return sq_aux_invalidtype(v, type); + } +} + +SQHash sq_gethash(HSQUIRRELVM v, SQInteger idx) +{ + SQObjectPtr &o = stack_get(v, idx); + return HashObj(o); +} + +SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_USERDATA,o); + (*p) = _userdataval(*o); + if(typetag) *typetag = _userdata(*o)->_typetag; + return SQ_OK; +} + +SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag) +{ + SQObjectPtr &o = stack_get(v,idx); + switch(type(o)) { + case OT_USERDATA: _userdata(o)->_typetag = typetag; break; + case OT_CLASS: _class(o)->_typetag = typetag; break; + default: return sq_throwerror(v,_SC("invalid object type")); + } + return SQ_OK; +} + +SQRESULT sq_getobjtypetag(const HSQOBJECT *o,SQUserPointer * typetag) +{ + switch(type(*o)) { + case OT_INSTANCE: *typetag = _instance(*o)->_class->_typetag; break; + case OT_USERDATA: *typetag = _userdata(*o)->_typetag; break; + case OT_CLASS: *typetag = _class(*o)->_typetag; break; + default: return SQ_ERROR; + } + return SQ_OK; +} + +SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag) +{ + SQObjectPtr &o = stack_get(v,idx); + if(SQ_FAILED(sq_getobjtypetag(&o,typetag))) + return sq_throwerror(v,_SC("invalid object type")); + return SQ_OK; +} + +SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_USERPOINTER,o); + (*p) = _userpointer(*o); + return SQ_OK; +} + +SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p) +{ + SQObjectPtr &o = stack_get(v,idx); + if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance")); + _instance(o)->_userpointer = p; + return SQ_OK; +} + +SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize) +{ + SQObjectPtr &o = stack_get(v,idx); + if(type(o) != OT_CLASS) return sq_throwerror(v,_SC("the object is not a class")); + if(_class(o)->_locked) return sq_throwerror(v,_SC("the class is locked")); + _class(o)->_udsize = udsize; + return SQ_OK; +} + + +SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag) +{ + SQObjectPtr &o = stack_get(v,idx); + if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance")); + (*p) = _instance(o)->_userpointer; + if(typetag != 0) { + SQClass *cl = _instance(o)->_class; + do{ + if(cl->_typetag == typetag) + return SQ_OK; + cl = cl->_base; + }while(cl != NULL); + return sq_throwerror(v,_SC("invalid type tag")); + } + return SQ_OK; +} + +SQInteger sq_gettop(HSQUIRRELVM v) +{ + return (v->_top) - v->_stackbase; +} + +void sq_settop(HSQUIRRELVM v, SQInteger newtop) +{ + SQInteger top = sq_gettop(v); + if(top > newtop) + sq_pop(v, top - newtop); + else + while(top++ < newtop) sq_pushnull(v); +} + +void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop) +{ + assert(v->_top >= nelemstopop); + v->Pop(nelemstopop); +} + +void sq_poptop(HSQUIRRELVM v) +{ + assert(v->_top >= 1); + v->Pop(); +} + + +void sq_remove(HSQUIRRELVM v, SQInteger idx) +{ + v->Remove(idx); +} + +SQInteger sq_cmp(HSQUIRRELVM v) +{ + SQInteger res; + v->ObjCmp(stack_get(v, -1), stack_get(v, -2),res); + return res; +} + +SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic) +{ + sq_aux_paramscheck(v, 3); + SQObjectPtr &self = stack_get(v, idx); + if(type(self) == OT_TABLE || type(self) == OT_CLASS) { + SQObjectPtr &key = v->GetUp(-2); + if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key")); + v->NewSlot(self, key, v->GetUp(-1),bstatic?true:false); + v->Pop(2); + } + return SQ_OK; +} + +SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval) +{ + sq_aux_paramscheck(v, 2); + SQObjectPtr *self; + _GETSAFE_OBJ(v, idx, OT_TABLE,self); + SQObjectPtr &key = v->GetUp(-1); + if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key")); + SQObjectPtr res; + if(!v->DeleteSlot(*self, key, res)){ + v->Pop(); + return SQ_ERROR; + } + if(pushval) v->GetUp(-1) = res; + else v->Pop(); + return SQ_OK; +} + +SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self = stack_get(v, idx); + if(v->Set(self, v->GetUp(-2), v->GetUp(-1),DONT_FALL_BACK)) { + v->Pop(2); + return SQ_OK; + } + return SQ_ERROR; +} + +SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self = stack_get(v, idx); + SQObjectPtr &key = v->GetUp(-2); + if(type(key) == OT_NULL) { + v->Pop(2); + return sq_throwerror(v, _SC("null key")); + } + switch(type(self)) { + case OT_TABLE: + _table(self)->NewSlot(key, v->GetUp(-1)); + v->Pop(2); + return SQ_OK; + break; + case OT_CLASS: + _class(self)->NewSlot(_ss(v), key, v->GetUp(-1),false); + v->Pop(2); + return SQ_OK; + break; + case OT_INSTANCE: + if(_instance(self)->Set(key, v->GetUp(-1))) { + v->Pop(2); + return SQ_OK; + } + break; + case OT_ARRAY: + if(v->Set(self, key, v->GetUp(-1),false)) { + v->Pop(2); + return SQ_OK; + } + break; + default: + v->Pop(2); + return sq_throwerror(v, _SC("rawset works only on array/table/class and instance")); + } + v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR; +} + +SQRESULT sq_newmember(HSQUIRRELVM v,SQInteger idx,SQBool bstatic) +{ + SQObjectPtr &self = stack_get(v, idx); + if(type(self) != OT_CLASS) return sq_throwerror(v, _SC("new member only works with classes")); + SQObjectPtr &key = v->GetUp(-3); + if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null key")); + if(!v->NewSlotA(self,key,v->GetUp(-2),v->GetUp(-1),bstatic?true:false,false)) + return SQ_ERROR; + return SQ_OK; +} + +SQRESULT sq_rawnewmember(HSQUIRRELVM v,SQInteger idx,SQBool bstatic) +{ + SQObjectPtr &self = stack_get(v, idx); + if(type(self) != OT_CLASS) return sq_throwerror(v, _SC("new member only works with classes")); + SQObjectPtr &key = v->GetUp(-3); + if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null key")); + if(!v->NewSlotA(self,key,v->GetUp(-2),v->GetUp(-1),bstatic?true:false,true)) + return SQ_ERROR; + return SQ_OK; +} + +SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self = stack_get(v, idx); + SQObjectPtr &mt = v->GetUp(-1); + SQObjectType type = type(self); + switch(type) { + case OT_TABLE: + if(type(mt) == OT_TABLE) { + if(!_table(self)->SetDelegate(_table(mt))) return sq_throwerror(v, _SC("delagate cycle")); v->Pop();} + else if(type(mt)==OT_NULL) { + _table(self)->SetDelegate(NULL); v->Pop(); } + else return sq_aux_invalidtype(v,type); + break; + case OT_USERDATA: + if(type(mt)==OT_TABLE) { + _userdata(self)->SetDelegate(_table(mt)); v->Pop(); } + else if(type(mt)==OT_NULL) { + _userdata(self)->SetDelegate(NULL); v->Pop(); } + else return sq_aux_invalidtype(v, type); + break; + default: + return sq_aux_invalidtype(v, type); + break; + } + return SQ_OK; +} + +SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval) +{ + sq_aux_paramscheck(v, 2); + SQObjectPtr *self; + _GETSAFE_OBJ(v, idx, OT_TABLE,self); + SQObjectPtr &key = v->GetUp(-1); + SQObjectPtr t; + if(_table(*self)->Get(key,t)) { + _table(*self)->Remove(key); + } + if(pushval != 0) + v->GetUp(-1) = t; + else + v->Pop(); + return SQ_OK; +} + +SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self=stack_get(v,idx); + switch(type(self)){ + case OT_TABLE: + case OT_USERDATA: + if(!_delegable(self)->_delegate){ + v->PushNull(); + break; + } + v->Push(SQObjectPtr(_delegable(self)->_delegate)); + break; + default: return sq_throwerror(v,_SC("wrong type")); break; + } + return SQ_OK; + +} + +SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self=stack_get(v,idx); + SQObjectPtr &obj = v->GetUp(-1); + if(v->Get(self,obj,obj,false,DONT_FALL_BACK)) + return SQ_OK; + v->Pop(); + return SQ_ERROR; +} + +SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self=stack_get(v,idx); + SQObjectPtr &obj = v->GetUp(-1); + switch(type(self)) { + case OT_TABLE: + if(_table(self)->Get(obj,obj)) + return SQ_OK; + break; + case OT_CLASS: + if(_class(self)->Get(obj,obj)) + return SQ_OK; + break; + case OT_INSTANCE: + if(_instance(self)->Get(obj,obj)) + return SQ_OK; + break; + case OT_ARRAY:{ + if(sq_isnumeric(obj)){ + if(_array(self)->Get(tointeger(obj),obj)) { + return SQ_OK; + } + } + else { + v->Pop(); + return sq_throwerror(v,_SC("invalid index type for an array")); + } + } + break; + default: + v->Pop(); + return sq_throwerror(v,_SC("rawget works only on array/table/instance and class")); + } + v->Pop(); + return sq_throwerror(v,_SC("the index doesn't exist")); +} + +SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po) +{ + *po=stack_get(v,idx); + return SQ_OK; +} + +const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx) +{ + SQUnsignedInteger cstksize=v->_callsstacksize; + SQUnsignedInteger lvl=(cstksize-level)-1; + SQInteger stackbase=v->_stackbase; + if(lvl_callsstack[(cstksize-i)-1]; + stackbase-=ci._prevstkbase; + } + SQVM::CallInfo &ci=v->_callsstack[lvl]; + if(type(ci._closure)!=OT_CLOSURE) + return NULL; + SQClosure *c=_closure(ci._closure); + SQFunctionProto *func=c->_function; + if(func->_noutervalues > (SQInteger)idx) { + v->Push(*_outer(c->_outervalues[idx])->_valptr); + return _stringval(func->_outervalues[idx]._name); + } + idx -= func->_noutervalues; + return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions)-1); + } + return NULL; +} + +void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj) +{ + v->Push(SQObjectPtr(obj)); +} + +void sq_resetobject(HSQOBJECT *po) +{ + po->_unVal.pUserPointer=NULL;po->_type=OT_NULL; +} + +SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err) +{ + v->_lasterror=SQString::Create(_ss(v),err); + return SQ_ERROR; +} + +SQRESULT sq_throwobject(HSQUIRRELVM v) +{ + v->_lasterror = v->GetUp(-1); + v->Pop(); + return SQ_ERROR; +} + + +void sq_reseterror(HSQUIRRELVM v) +{ + v->_lasterror.Null(); +} + +void sq_getlasterror(HSQUIRRELVM v) +{ + v->Push(v->_lasterror); +} + +SQRESULT sq_reservestack(HSQUIRRELVM v,SQInteger nsize) +{ + if (((SQUnsignedInteger)v->_top + nsize) > v->_stack.size()) { + if(v->_nmetamethodscall) { + return sq_throwerror(v,_SC("cannot resize stack while in a metamethod")); + } + v->_stack.resize(v->_stack.size() + ((v->_top + nsize) - v->_stack.size())); + } + return SQ_OK; +} + +SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror) +{ + if (type(v->GetUp(-1)) == OT_GENERATOR) + { + v->PushNull(); //retval + if (!v->Execute(v->GetUp(-2), 0, v->_top, v->GetUp(-1), raiseerror, SQVM::ET_RESUME_GENERATOR)) + {v->Raise_Error(v->_lasterror); return SQ_ERROR;} + if(!retval) + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v,_SC("only generators can be resumed")); +} + +SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror) +{ + SQObjectPtr res; + if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false)){ + + if(!v->_suspended) { + v->Pop(params);//pop closure and args + } + if(retval){ + v->Push(res); return SQ_OK; + } + return SQ_OK; + } + else { + v->Pop(params); + return SQ_ERROR; + } + if(!v->_suspended) + v->Pop(params); + return sq_throwerror(v,_SC("call failed")); +} + +SQRESULT sq_suspendvm(HSQUIRRELVM v) +{ + return v->Suspend(); +} + +SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror,SQBool throwerror) +{ + SQObjectPtr ret; + if(!v->_suspended) + return sq_throwerror(v,_SC("cannot resume a vm that is not running any code")); + SQInteger target = v->_suspended_target; + if(wakeupret) { + if(target != -1) { + v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1); //retval + } + v->Pop(); + } else if(target != -1) { v->GetAt(v->_stackbase+v->_suspended_target).Null(); } + SQObjectPtr dummy; + if(!v->Execute(dummy,-1,-1,ret,raiseerror,throwerror?SQVM::ET_RESUME_THROW_VM : SQVM::ET_RESUME_VM)) { + return SQ_ERROR; + } + if(retval) + v->Push(ret); + return SQ_OK; +} + +void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook) +{ + if(sq_gettop(v) >= 1){ + SQObjectPtr &ud=stack_get(v,idx); + switch( type(ud) ) { + case OT_USERDATA: _userdata(ud)->_hook = hook; break; + case OT_INSTANCE: _instance(ud)->_hook = hook; break; + case OT_CLASS: _class(ud)->_hook = hook; break; + default: break; //shutup compiler + } + } +} + +SQRELEASEHOOK sq_getreleasehook(HSQUIRRELVM v,SQInteger idx) +{ + if(sq_gettop(v) >= 1){ + SQObjectPtr &ud=stack_get(v,idx); + switch( type(ud) ) { + case OT_USERDATA: return _userdata(ud)->_hook; break; + case OT_INSTANCE: return _instance(ud)->_hook; break; + case OT_CLASS: return _class(ud)->_hook; break; + default: break; //shutup compiler + } + } + return NULL; +} + +void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f) +{ + _ss(v)->_compilererrorhandler = f; +} + +SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, -1, OT_CLOSURE,o); + unsigned short tag = SQ_BYTECODE_STREAM_TAG; + if(_closure(*o)->_function->_noutervalues) + return sq_throwerror(v,_SC("a closure with free valiables bound it cannot be serialized")); + if(w(up,&tag,2) != 2) + return sq_throwerror(v,_SC("io error")); + if(!_closure(*o)->Save(v,up,w)) + return SQ_ERROR; + return SQ_OK; +} + +SQRESULT sq_readclosure(HSQUIRRELVM v,SQREADFUNC r,SQUserPointer up) +{ + SQObjectPtr closure; + + unsigned short tag; + if(r(up,&tag,2) != 2) + return sq_throwerror(v,_SC("io error")); + if(tag != SQ_BYTECODE_STREAM_TAG) + return sq_throwerror(v,_SC("invalid stream")); + if(!SQClosure::Load(v,up,r,closure)) + return SQ_ERROR; + v->Push(closure); + return SQ_OK; +} + +SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize) +{ + return _ss(v)->GetScratchPad(minsize); +} + +SQRESULT sq_resurrectunreachable(HSQUIRRELVM v) +{ +#ifndef NO_GARBAGE_COLLECTOR + _ss(v)->ResurrectUnreachable(v); + return SQ_OK; +#else + return sq_throwerror(v,_SC("sq_resurrectunreachable requires a garbage collector build")); +#endif +} + +SQInteger sq_collectgarbage(HSQUIRRELVM v) +{ +#ifndef NO_GARBAGE_COLLECTOR + return _ss(v)->CollectGarbage(v); +#else + return -1; +#endif +} + +SQRESULT sq_getcallee(HSQUIRRELVM v) +{ + if(v->_callsstacksize > 1) + { + v->Push(v->_callsstack[v->_callsstacksize - 2]._closure); + return SQ_OK; + } + return sq_throwerror(v,_SC("no closure in the calls stack")); +} + +const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval) +{ + SQObjectPtr &self=stack_get(v,idx); + const SQChar *name = NULL; + switch(type(self)) + { + case OT_CLOSURE:{ + SQClosure *clo = _closure(self); + SQFunctionProto *fp = clo->_function; + if(((SQUnsignedInteger)fp->_noutervalues) > nval) { + v->Push(*(_outer(clo->_outervalues[nval])->_valptr)); + SQOuterVar &ov = fp->_outervalues[nval]; + name = _stringval(ov._name); + } + } + break; + case OT_NATIVECLOSURE:{ + SQNativeClosure *clo = _nativeclosure(self); + if(clo->_noutervalues > nval) { + v->Push(clo->_outervalues[nval]); + name = _SC("@NATIVE"); + } + } + break; + default: break; //shutup compiler + } + return name; +} + +SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval) +{ + SQObjectPtr &self=stack_get(v,idx); + switch(type(self)) + { + case OT_CLOSURE:{ + SQFunctionProto *fp = _closure(self)->_function; + if(((SQUnsignedInteger)fp->_noutervalues) > nval){ + *(_outer(_closure(self)->_outervalues[nval])->_valptr) = stack_get(v,-1); + } + else return sq_throwerror(v,_SC("invalid free var index")); + } + break; + case OT_NATIVECLOSURE: + if(_nativeclosure(self)->_noutervalues > nval){ + _nativeclosure(self)->_outervalues[nval] = stack_get(v,-1); + } + else return sq_throwerror(v,_SC("invalid free var index")); + break; + default: + return sq_aux_invalidtype(v,type(self)); + } + v->Pop(); + return SQ_OK; +} + +SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + SQObjectPtr &key = stack_get(v,-2); + SQObjectPtr &val = stack_get(v,-1); + SQObjectPtr attrs; + if(type(key) == OT_NULL) { + attrs = _class(*o)->_attributes; + _class(*o)->_attributes = val; + v->Pop(2); + v->Push(attrs); + return SQ_OK; + }else if(_class(*o)->GetAttributes(key,attrs)) { + _class(*o)->SetAttributes(key,val); + v->Pop(2); + v->Push(attrs); + return SQ_OK; + } + return sq_throwerror(v,_SC("wrong index")); +} + +SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + SQObjectPtr &key = stack_get(v,-1); + SQObjectPtr attrs; + if(type(key) == OT_NULL) { + attrs = _class(*o)->_attributes; + v->Pop(); + v->Push(attrs); + return SQ_OK; + } + else if(_class(*o)->GetAttributes(key,attrs)) { + v->Pop(); + v->Push(attrs); + return SQ_OK; + } + return sq_throwerror(v,_SC("wrong index")); +} + +SQRESULT sq_getmemberhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + SQObjectPtr &key = stack_get(v,-1); + SQTable *m = _class(*o)->_members; + SQObjectPtr val; + if(m->Get(key,val)) { + handle->_static = _isfield(val) ? SQFalse : SQTrue; + handle->_index = _member_idx(val); + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v,_SC("wrong index")); +} + +SQRESULT _getmemberbyhandle(HSQUIRRELVM v,SQObjectPtr &self,const HSQMEMBERHANDLE *handle,SQObjectPtr *&val) +{ + switch(type(self)) { + case OT_INSTANCE: { + SQInstance *i = _instance(self); + if(handle->_static) { + SQClass *c = i->_class; + val = &c->_methods[handle->_index].val; + } + else { + val = &i->_values[handle->_index]; + + } + } + break; + case OT_CLASS: { + SQClass *c = _class(self); + if(handle->_static) { + val = &c->_methods[handle->_index].val; + } + else { + val = &c->_defaultvalues[handle->_index].val; + } + } + break; + default: + return sq_throwerror(v,_SC("wrong type(expected class or instance)")); + } + return SQ_OK; +} + +SQRESULT sq_getbyhandle(HSQUIRRELVM v,SQInteger idx,const HSQMEMBERHANDLE *handle) +{ + SQObjectPtr &self = stack_get(v,idx); + SQObjectPtr *val = NULL; + if(SQ_FAILED(_getmemberbyhandle(v,self,handle,val))) { + return SQ_ERROR; + } + v->Push(_realval(*val)); + return SQ_OK; +} + +SQRESULT sq_setbyhandle(HSQUIRRELVM v,SQInteger idx,const HSQMEMBERHANDLE *handle) +{ + SQObjectPtr &self = stack_get(v,idx); + SQObjectPtr &newval = stack_get(v,-1); + SQObjectPtr *val = NULL; + if(SQ_FAILED(_getmemberbyhandle(v,self,handle,val))) { + return SQ_ERROR; + } + *val = newval; + v->Pop(); + return SQ_OK; +} + +SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + if(_class(*o)->_base) + v->Push(SQObjectPtr(_class(*o)->_base)); + else + v->PushNull(); + return SQ_OK; +} + +SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_INSTANCE,o); + v->Push(SQObjectPtr(_instance(*o)->_class)); + return SQ_OK; +} + +SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + v->Push(_class(*o)->CreateInstance()); + return SQ_OK; +} + +void sq_weakref(HSQUIRRELVM v,SQInteger idx) +{ + SQObject &o=stack_get(v,idx); + if(ISREFCOUNTED(type(o))) { + v->Push(_refcounted(o)->GetWeakRef(type(o))); + return; + } + v->Push(o); +} + +SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v,idx); + if(type(o) != OT_WEAKREF) { + return sq_throwerror(v,_SC("the object must be a weakref")); + } + v->Push(_weakref(o)->_obj); + return SQ_OK; +} + +SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t) +{ + SQSharedState *ss = _ss(v); + switch(t) { + case OT_TABLE: v->Push(ss->_table_default_delegate); break; + case OT_ARRAY: v->Push(ss->_array_default_delegate); break; + case OT_STRING: v->Push(ss->_string_default_delegate); break; + case OT_INTEGER: case OT_FLOAT: v->Push(ss->_number_default_delegate); break; + case OT_GENERATOR: v->Push(ss->_generator_default_delegate); break; + case OT_CLOSURE: case OT_NATIVECLOSURE: v->Push(ss->_closure_default_delegate); break; + case OT_THREAD: v->Push(ss->_thread_default_delegate); break; + case OT_CLASS: v->Push(ss->_class_default_delegate); break; + case OT_INSTANCE: v->Push(ss->_instance_default_delegate); break; + case OT_WEAKREF: v->Push(ss->_weakref_default_delegate); break; + default: return sq_throwerror(v,_SC("the type doesn't have a default delegate")); + } + return SQ_OK; +} + +SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr o=stack_get(v,idx),&refpos = stack_get(v,-1),realkey,val; + if(type(o) == OT_GENERATOR) { + return sq_throwerror(v,_SC("cannot iterate a generator")); + } + int faketojump; + if(!v->FOREACH_OP(o,realkey,val,refpos,0,666,faketojump)) + return SQ_ERROR; + if(faketojump != 666) { + v->Push(realkey); + v->Push(val); + return SQ_OK; + } + return SQ_ERROR; +} + +struct BufState{ + const SQChar *buf; + SQInteger ptr; + SQInteger size; +}; + +SQInteger buf_lexfeed(SQUserPointer file) +{ + BufState *buf=(BufState*)file; + if(buf->size<(buf->ptr+1)) + return 0; + return buf->buf[buf->ptr++]; +} + +SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror) { + BufState buf; + buf.buf = s; + buf.size = size; + buf.ptr = 0; + return sq_compile(v, buf_lexfeed, &buf, sourcename, raiseerror); +} + +void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx) +{ + dest->Push(stack_get(src,idx)); +} + +void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc,SQPRINTFUNCTION errfunc) +{ + _ss(v)->_printfunc = printfunc; + _ss(v)->_errorfunc = errfunc; +} + +SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v) +{ + return _ss(v)->_printfunc; +} + +SQPRINTFUNCTION sq_geterrorfunc(HSQUIRRELVM v) +{ + return _ss(v)->_errorfunc; +} + +void *sq_malloc(SQUnsignedInteger size) +{ + return SQ_MALLOC(size); +} + +void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize) +{ + return SQ_REALLOC(p,oldsize,newsize); +} + +void sq_free(void *p,SQUnsignedInteger size) +{ + SQ_FREE(p,size); +} diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqarray.h b/src/modules/app_sqlang/squirrel/squirrel/sqarray.h new file mode 100644 index 00000000000..7f1d1476ed4 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqarray.h @@ -0,0 +1,94 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQARRAY_H_ +#define _SQARRAY_H_ + +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); + } +public: + static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){ + SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray)); + new (newarray) SQArray(ss,nInitialSize); + return newarray; + } +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + SQObjectType GetType() {return OT_ARRAY;} +#endif + 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(_opt_ss(this),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; +}; +#endif //_SQARRAY_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqbaselib.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqbaselib.cpp new file mode 100644 index 00000000000..e1d5c2b69d9 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqbaselib.cpp @@ -0,0 +1,1266 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqstring.h" +#include "sqtable.h" +#include "sqarray.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "sqclass.h" +#include +#include +#include + +static bool str2num(const SQChar *s,SQObjectPtr &res,SQInteger base) +{ + SQChar *end; + const SQChar *e = s; + bool iseintbase = base > 13; //to fix error converting hexadecimals with e like 56f0791e + bool isfloat = false; + SQChar c; + while((c = *e) != _SC('\0')) + { + if (c == _SC('.') || (!iseintbase && (c == _SC('E') || c == _SC('e')))) { //e and E is for scientific notation + isfloat = true; + break; + } + e++; + } + if(isfloat){ + SQFloat r = SQFloat(scstrtod(s,&end)); + if(s == end) return false; + res = r; + } + else{ + SQInteger r = SQInteger(scstrtol(s,&end,(int)base)); + if(s == end) return false; + res = r; + } + return true; +} + +static SQInteger base_dummy(HSQUIRRELVM SQ_UNUSED_ARG(v)) +{ + return 0; +} + +#ifndef NO_GARBAGE_COLLECTOR +static SQInteger base_collectgarbage(HSQUIRRELVM v) +{ + sq_pushinteger(v, sq_collectgarbage(v)); + return 1; +} +static SQInteger base_resurectureachable(HSQUIRRELVM v) +{ + sq_resurrectunreachable(v); + return 1; +} +#endif + +static SQInteger base_getroottable(HSQUIRRELVM v) +{ + v->Push(v->_roottable); + return 1; +} + +static SQInteger base_getconsttable(HSQUIRRELVM v) +{ + v->Push(_ss(v)->_consts); + return 1; +} + + +static SQInteger base_setroottable(HSQUIRRELVM v) +{ + SQObjectPtr o = v->_roottable; + if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR; + v->Push(o); + return 1; +} + +static SQInteger base_setconsttable(HSQUIRRELVM v) +{ + SQObjectPtr o = _ss(v)->_consts; + if(SQ_FAILED(sq_setconsttable(v))) return SQ_ERROR; + v->Push(o); + return 1; +} + +static SQInteger base_seterrorhandler(HSQUIRRELVM v) +{ + sq_seterrorhandler(v); + return 0; +} + +static SQInteger base_setdebughook(HSQUIRRELVM v) +{ + sq_setdebughook(v); + return 0; +} + +static SQInteger base_enabledebuginfo(HSQUIRRELVM v) +{ + SQObjectPtr &o=stack_get(v,2); + + sq_enabledebuginfo(v,SQVM::IsFalse(o)?SQFalse:SQTrue); + return 0; +} + +static SQInteger __getcallstackinfos(HSQUIRRELVM v,SQInteger level) +{ + SQStackInfos si; + SQInteger seq = 0; + const SQChar *name = NULL; + + if (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; + sq_newtable(v); + sq_pushstring(v, _SC("func"), -1); + sq_pushstring(v, fn, -1); + sq_newslot(v, -3, SQFalse); + sq_pushstring(v, _SC("src"), -1); + sq_pushstring(v, src, -1); + sq_newslot(v, -3, SQFalse); + sq_pushstring(v, _SC("line"), -1); + sq_pushinteger(v, si.line); + sq_newslot(v, -3, SQFalse); + sq_pushstring(v, _SC("locals"), -1); + sq_newtable(v); + seq=0; + while ((name = sq_getlocal(v, level, seq))) { + sq_pushstring(v, name, -1); + sq_push(v, -2); + sq_newslot(v, -4, SQFalse); + sq_pop(v, 1); + seq++; + } + sq_newslot(v, -3, SQFalse); + return 1; + } + + return 0; +} +static SQInteger base_getstackinfos(HSQUIRRELVM v) +{ + SQInteger level; + sq_getinteger(v, -1, &level); + return __getcallstackinfos(v,level); +} + +static SQInteger base_assert(HSQUIRRELVM v) +{ + if(SQVM::IsFalse(stack_get(v,2))){ + return sq_throwerror(v,_SC("assertion failed")); + } + return 0; +} + +static SQInteger get_slice_params(HSQUIRRELVM v,SQInteger &sidx,SQInteger &eidx,SQObjectPtr &o) +{ + SQInteger top = sq_gettop(v); + sidx=0; + eidx=0; + o=stack_get(v,1); + if(top>1){ + SQObjectPtr &start=stack_get(v,2); + if(type(start)!=OT_NULL && sq_isnumeric(start)){ + sidx=tointeger(start); + } + } + if(top>2){ + SQObjectPtr &end=stack_get(v,3); + if(sq_isnumeric(end)){ + eidx=tointeger(end); + } + } + else { + eidx = sq_getsize(v,1); + } + return 1; +} + +static SQInteger base_print(HSQUIRRELVM v) +{ + const SQChar *str; + if(SQ_SUCCEEDED(sq_tostring(v,2))) + { + if(SQ_SUCCEEDED(sq_getstring(v,-1,&str))) { + if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),str); + return 0; + } + } + return SQ_ERROR; +} + +static SQInteger base_error(HSQUIRRELVM v) +{ + const SQChar *str; + if(SQ_SUCCEEDED(sq_tostring(v,2))) + { + if(SQ_SUCCEEDED(sq_getstring(v,-1,&str))) { + if(_ss(v)->_errorfunc) _ss(v)->_errorfunc(v,_SC("%s"),str); + return 0; + } + } + return SQ_ERROR; +} + +static SQInteger base_compilestring(HSQUIRRELVM v) +{ + SQInteger nargs=sq_gettop(v); + const SQChar *src=NULL,*name=_SC("unnamedbuffer"); + SQInteger size; + sq_getstring(v,2,&src); + size=sq_getsize(v,2); + if(nargs>2){ + sq_getstring(v,3,&name); + } + if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse))) + return 1; + else + return SQ_ERROR; +} + +static SQInteger base_newthread(HSQUIRRELVM v) +{ + SQObjectPtr &func = stack_get(v,2); + SQInteger stksize = (_closure(func)->_function->_stacksize << 1) +2; + HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize); + sq_move(newv,v,-2); + return 1; +} + +static SQInteger base_suspend(HSQUIRRELVM v) +{ + return sq_suspendvm(v); +} + +static SQInteger base_array(HSQUIRRELVM v) +{ + SQArray *a; + SQObject &size = stack_get(v,2); + if(sq_gettop(v) > 2) { + a = SQArray::Create(_ss(v),0); + a->Resize(tointeger(size),stack_get(v,3)); + } + else { + a = SQArray::Create(_ss(v),tointeger(size)); + } + v->Push(a); + return 1; +} + +static SQInteger base_type(HSQUIRRELVM v) +{ + SQObjectPtr &o = stack_get(v,2); + v->Push(SQString::Create(_ss(v),GetTypeName(o),-1)); + return 1; +} + +static SQInteger base_callee(HSQUIRRELVM v) +{ + if(v->_callsstacksize > 1) + { + v->Push(v->_callsstack[v->_callsstacksize - 2]._closure); + return 1; + } + return sq_throwerror(v,_SC("no closure in the calls stack")); +} + +static const SQRegFunction base_funcs[]={ + //generic + {_SC("seterrorhandler"),base_seterrorhandler,2, NULL}, + {_SC("setdebughook"),base_setdebughook,2, NULL}, + {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL}, + {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")}, + {_SC("getroottable"),base_getroottable,1, NULL}, + {_SC("setroottable"),base_setroottable,2, NULL}, + {_SC("getconsttable"),base_getconsttable,1, NULL}, + {_SC("setconsttable"),base_setconsttable,2, NULL}, + {_SC("assert"),base_assert,2, NULL}, + {_SC("print"),base_print,2, NULL}, + {_SC("error"),base_error,2, NULL}, + {_SC("compilestring"),base_compilestring,-2, _SC(".ss")}, + {_SC("newthread"),base_newthread,2, _SC(".c")}, + {_SC("suspend"),base_suspend,-1, NULL}, + {_SC("array"),base_array,-2, _SC(".n")}, + {_SC("type"),base_type,2, NULL}, + {_SC("callee"),base_callee,0,NULL}, + {_SC("dummy"),base_dummy,0,NULL}, +#ifndef NO_GARBAGE_COLLECTOR + {_SC("collectgarbage"),base_collectgarbage,0, NULL}, + {_SC("resurrectunreachable"),base_resurectureachable,0, NULL}, +#endif + {NULL,(SQFUNCTION)0,0,NULL} +}; + +void sq_base_register(HSQUIRRELVM v) +{ + SQInteger i=0; + sq_pushroottable(v); + while(base_funcs[i].name!=0) { + sq_pushstring(v,base_funcs[i].name,-1); + sq_newclosure(v,base_funcs[i].f,0); + sq_setnativeclosurename(v,-1,base_funcs[i].name); + sq_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask); + sq_newslot(v,-3, SQFalse); + i++; + } + + sq_pushstring(v,_SC("_versionnumber_"),-1); + sq_pushinteger(v,SQUIRREL_VERSION_NUMBER); + sq_newslot(v,-3, SQFalse); + sq_pushstring(v,_SC("_version_"),-1); + sq_pushstring(v,SQUIRREL_VERSION,-1); + sq_newslot(v,-3, SQFalse); + sq_pushstring(v,_SC("_charsize_"),-1); + sq_pushinteger(v,sizeof(SQChar)); + sq_newslot(v,-3, SQFalse); + sq_pushstring(v,_SC("_intsize_"),-1); + sq_pushinteger(v,sizeof(SQInteger)); + sq_newslot(v,-3, SQFalse); + sq_pushstring(v,_SC("_floatsize_"),-1); + sq_pushinteger(v,sizeof(SQFloat)); + sq_newslot(v,-3, SQFalse); + sq_pop(v,1); +} + +static SQInteger default_delegate_len(HSQUIRRELVM v) +{ + v->Push(SQInteger(sq_getsize(v,1))); + return 1; +} + +static SQInteger default_delegate_tofloat(HSQUIRRELVM v) +{ + SQObjectPtr &o=stack_get(v,1); + switch(type(o)){ + case OT_STRING:{ + SQObjectPtr res; + if(str2num(_stringval(o),res,10)){ + v->Push(SQObjectPtr(tofloat(res))); + break; + }} + return sq_throwerror(v, _SC("cannot convert the string")); + break; + case OT_INTEGER:case OT_FLOAT: + v->Push(SQObjectPtr(tofloat(o))); + break; + case OT_BOOL: + v->Push(SQObjectPtr((SQFloat)(_integer(o)?1:0))); + break; + default: + v->PushNull(); + break; + } + return 1; +} + +static SQInteger default_delegate_tointeger(HSQUIRRELVM v) +{ + SQObjectPtr &o=stack_get(v,1); + SQInteger base = 10; + if(sq_gettop(v) > 1) { + sq_getinteger(v,2,&base); + } + switch(type(o)){ + case OT_STRING:{ + SQObjectPtr res; + if(str2num(_stringval(o),res,base)){ + v->Push(SQObjectPtr(tointeger(res))); + break; + }} + return sq_throwerror(v, _SC("cannot convert the string")); + break; + case OT_INTEGER:case OT_FLOAT: + v->Push(SQObjectPtr(tointeger(o))); + break; + case OT_BOOL: + v->Push(SQObjectPtr(_integer(o)?(SQInteger)1:(SQInteger)0)); + break; + default: + v->PushNull(); + break; + } + return 1; +} + +static SQInteger default_delegate_tostring(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_tostring(v,1))) + return SQ_ERROR; + return 1; +} + +static SQInteger obj_delegate_weakref(HSQUIRRELVM v) +{ + sq_weakref(v,1); + return 1; +} + +static SQInteger obj_clear(HSQUIRRELVM v) +{ + return sq_clear(v,-1); +} + + +static SQInteger number_delegate_tochar(HSQUIRRELVM v) +{ + SQObject &o=stack_get(v,1); + SQChar c = (SQChar)tointeger(o); + v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1)); + return 1; +} + + + +///////////////////////////////////////////////////////////////// +//TABLE DEFAULT DELEGATE + +static SQInteger table_rawdelete(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_rawdeleteslot(v,1,SQTrue))) + return SQ_ERROR; + return 1; +} + + +static SQInteger container_rawexists(HSQUIRRELVM v) +{ + if(SQ_SUCCEEDED(sq_rawget(v,-2))) { + sq_pushbool(v,SQTrue); + return 1; + } + sq_pushbool(v,SQFalse); + return 1; +} + +static SQInteger container_rawset(HSQUIRRELVM v) +{ + return sq_rawset(v,-3); +} + + +static SQInteger container_rawget(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR; +} + +static SQInteger table_setdelegate(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_setdelegate(v,-2))) + return SQ_ERROR; + sq_push(v,-1); // -1 because sq_setdelegate pops 1 + return 1; +} + +static SQInteger table_getdelegate(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_getdelegate(v,-1))?1:SQ_ERROR; +} + +const SQRegFunction SQSharedState::_table_default_delegate_funcz[]={ + {_SC("len"),default_delegate_len,1, _SC("t")}, + {_SC("rawget"),container_rawget,2, _SC("t")}, + {_SC("rawset"),container_rawset,3, _SC("t")}, + {_SC("rawdelete"),table_rawdelete,2, _SC("t")}, + {_SC("rawin"),container_rawexists,2, _SC("t")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("clear"),obj_clear,1, _SC(".")}, + {_SC("setdelegate"),table_setdelegate,2, _SC(".t|o")}, + {_SC("getdelegate"),table_getdelegate,1, _SC(".")}, + {NULL,(SQFUNCTION)0,0,NULL} +}; + +//ARRAY DEFAULT DELEGATE/////////////////////////////////////// + +static SQInteger array_append(HSQUIRRELVM v) +{ + return sq_arrayappend(v,-2); +} + +static SQInteger array_extend(HSQUIRRELVM v) +{ + _array(stack_get(v,1))->Extend(_array(stack_get(v,2))); + return 0; +} + +static SQInteger array_reverse(HSQUIRRELVM v) +{ + return sq_arrayreverse(v,-1); +} + +static SQInteger array_pop(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR; +} + +static SQInteger array_top(HSQUIRRELVM v) +{ + SQObject &o=stack_get(v,1); + if(_array(o)->Size()>0){ + v->Push(_array(o)->Top()); + return 1; + } + else return sq_throwerror(v,_SC("top() on a empty array")); +} + +static SQInteger array_insert(HSQUIRRELVM v) +{ + SQObject &o=stack_get(v,1); + SQObject &idx=stack_get(v,2); + SQObject &val=stack_get(v,3); + if(!_array(o)->Insert(tointeger(idx),val)) + return sq_throwerror(v,_SC("index out of range")); + return 0; +} + +static SQInteger array_remove(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v, 1); + SQObject &idx = stack_get(v, 2); + if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type")); + SQObjectPtr val; + if(_array(o)->Get(tointeger(idx), val)) { + _array(o)->Remove(tointeger(idx)); + v->Push(val); + return 1; + } + return sq_throwerror(v, _SC("idx out of range")); +} + +static SQInteger array_resize(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v, 1); + SQObject &nsize = stack_get(v, 2); + SQObjectPtr fill; + if(sq_isnumeric(nsize)) { + if(sq_gettop(v) > 2) + fill = stack_get(v, 3); + _array(o)->Resize(tointeger(nsize),fill); + return 0; + } + return sq_throwerror(v, _SC("size must be a number")); +} + +static SQInteger __map_array(SQArray *dest,SQArray *src,HSQUIRRELVM v) { + SQObjectPtr temp; + SQInteger size = src->Size(); + for(SQInteger n = 0; n < size; n++) { + src->Get(n,temp); + v->Push(src); + v->Push(temp); + if(SQ_FAILED(sq_call(v,2,SQTrue,SQFalse))) { + return SQ_ERROR; + } + dest->Set(n,v->GetUp(-1)); + v->Pop(); + } + return 0; +} + +static SQInteger array_map(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v,1); + SQInteger size = _array(o)->Size(); + SQObjectPtr ret = SQArray::Create(_ss(v),size); + if(SQ_FAILED(__map_array(_array(ret),_array(o),v))) + return SQ_ERROR; + v->Push(ret); + return 1; +} + +static SQInteger array_apply(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v,1); + if(SQ_FAILED(__map_array(_array(o),_array(o),v))) + return SQ_ERROR; + return 0; +} + +static SQInteger array_reduce(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v,1); + SQArray *a = _array(o); + SQInteger size = a->Size(); + if(size == 0) { + return 0; + } + SQObjectPtr res; + a->Get(0,res); + if(size > 1) { + SQObjectPtr other; + for(SQInteger n = 1; n < size; n++) { + a->Get(n,other); + v->Push(o); + v->Push(res); + v->Push(other); + if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) { + return SQ_ERROR; + } + res = v->GetUp(-1); + v->Pop(); + } + } + v->Push(res); + return 1; +} + +static SQInteger array_filter(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v,1); + SQArray *a = _array(o); + SQObjectPtr ret = SQArray::Create(_ss(v),0); + SQInteger size = a->Size(); + SQObjectPtr val; + for(SQInteger n = 0; n < size; n++) { + a->Get(n,val); + v->Push(o); + v->Push(n); + v->Push(val); + if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) { + return SQ_ERROR; + } + if(!SQVM::IsFalse(v->GetUp(-1))) { + _array(ret)->Append(val); + } + v->Pop(); + } + v->Push(ret); + return 1; +} + +static SQInteger array_find(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v,1); + SQObjectPtr &val = stack_get(v,2); + SQArray *a = _array(o); + SQInteger size = a->Size(); + SQObjectPtr temp; + for(SQInteger n = 0; n < size; n++) { + bool res = false; + a->Get(n,temp); + if(SQVM::IsEqual(temp,val,res) && res) { + v->Push(n); + return 1; + } + } + return 0; +} + + +static bool _sort_compare(HSQUIRRELVM v,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret) +{ + if(func < 0) { + if(!v->ObjCmp(a,b,ret)) return false; + } + else { + SQInteger top = sq_gettop(v); + sq_push(v, func); + sq_pushroottable(v); + v->Push(a); + v->Push(b); + if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) { + if(!sq_isstring( v->_lasterror)) + v->Raise_Error(_SC("compare func failed")); + return false; + } + if(SQ_FAILED(sq_getinteger(v, -1, &ret))) { + v->Raise_Error(_SC("numeric value expected as return value of the compare function")); + return false; + } + sq_settop(v, top); + return true; + } + return true; +} + +static bool _hsort_sift_down(HSQUIRRELVM v,SQArray *arr, SQInteger root, SQInteger bottom, SQInteger func) +{ + SQInteger maxChild; + SQInteger done = 0; + SQInteger ret; + SQInteger root2; + while (((root2 = root * 2) <= bottom) && (!done)) + { + if (root2 == bottom) { + maxChild = root2; + } + else { + if(!_sort_compare(v,arr->_values[root2],arr->_values[root2 + 1],func,ret)) + return false; + if (ret > 0) { + maxChild = root2; + } + else { + maxChild = root2 + 1; + } + } + + if(!_sort_compare(v,arr->_values[root],arr->_values[maxChild],func,ret)) + return false; + if (ret < 0) { + if (root == maxChild) { + v->Raise_Error(_SC("inconsistent compare function")); + return false; // We'd be swapping ourselve. The compare function is incorrect + } + + _Swap(arr->_values[root],arr->_values[maxChild]); + root = maxChild; + } + else { + done = 1; + } + } + return true; +} + +static bool _hsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger SQ_UNUSED_ARG(l), SQInteger SQ_UNUSED_ARG(r),SQInteger func) +{ + SQArray *a = _array(arr); + SQInteger i; + SQInteger array_size = a->Size(); + for (i = (array_size / 2); i >= 0; i--) { + if(!_hsort_sift_down(v,a, i, array_size - 1,func)) return false; + } + + for (i = array_size-1; i >= 1; i--) + { + _Swap(a->_values[0],a->_values[i]); + if(!_hsort_sift_down(v,a, 0, i-1,func)) return false; + } + return true; +} + +static SQInteger array_sort(HSQUIRRELVM v) +{ + SQInteger func = -1; + SQObjectPtr &o = stack_get(v,1); + if(_array(o)->Size() > 1) { + if(sq_gettop(v) == 2) func = 2; + if(!_hsort(v, o, 0, _array(o)->Size()-1, func)) + return SQ_ERROR; + + } + return 0; +} + +static SQInteger array_slice(HSQUIRRELVM v) +{ + SQInteger sidx,eidx; + SQObjectPtr o; + if(get_slice_params(v,sidx,eidx,o)==-1)return -1; + SQInteger alen = _array(o)->Size(); + if(sidx < 0)sidx = alen + sidx; + if(eidx < 0)eidx = alen + eidx; + if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes")); + if(eidx > alen || sidx < 0)return sq_throwerror(v, _SC("slice out of range")); + SQArray *arr=SQArray::Create(_ss(v),eidx-sidx); + SQObjectPtr t; + SQInteger count=0; + for(SQInteger i=sidx;iGet(i,t); + arr->Set(count++,t); + } + v->Push(arr); + return 1; + +} + +const SQRegFunction SQSharedState::_array_default_delegate_funcz[]={ + {_SC("len"),default_delegate_len,1, _SC("a")}, + {_SC("append"),array_append,2, _SC("a")}, + {_SC("extend"),array_extend,2, _SC("aa")}, + {_SC("push"),array_append,2, _SC("a")}, + {_SC("pop"),array_pop,1, _SC("a")}, + {_SC("top"),array_top,1, _SC("a")}, + {_SC("insert"),array_insert,3, _SC("an")}, + {_SC("remove"),array_remove,2, _SC("an")}, + {_SC("resize"),array_resize,-2, _SC("an")}, + {_SC("reverse"),array_reverse,1, _SC("a")}, + {_SC("sort"),array_sort,-1, _SC("ac")}, + {_SC("slice"),array_slice,-1, _SC("ann")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("clear"),obj_clear,1, _SC(".")}, + {_SC("map"),array_map,2, _SC("ac")}, + {_SC("apply"),array_apply,2, _SC("ac")}, + {_SC("reduce"),array_reduce,2, _SC("ac")}, + {_SC("filter"),array_filter,2, _SC("ac")}, + {_SC("find"),array_find,2, _SC("a.")}, + {NULL,(SQFUNCTION)0,0,NULL} +}; + +//STRING DEFAULT DELEGATE////////////////////////// +static SQInteger string_slice(HSQUIRRELVM v) +{ + SQInteger sidx,eidx; + SQObjectPtr o; + if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1; + SQInteger slen = _string(o)->_len; + if(sidx < 0)sidx = slen + sidx; + if(eidx < 0)eidx = slen + eidx; + if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes")); + if(eidx > slen || sidx < 0) return sq_throwerror(v, _SC("slice out of range")); + v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx)); + return 1; +} + +static SQInteger string_find(HSQUIRRELVM v) +{ + SQInteger top,start_idx=0; + const SQChar *str,*substr,*ret; + if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){ + if(top>2)sq_getinteger(v,3,&start_idx); + if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){ + ret=scstrstr(&str[start_idx],substr); + if(ret){ + sq_pushinteger(v,(SQInteger)(ret-str)); + return 1; + } + } + return 0; + } + return sq_throwerror(v,_SC("invalid param")); +} + +#define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \ +{\ + SQInteger sidx,eidx; \ + SQObjectPtr str; \ + if(SQ_FAILED(get_slice_params(v,sidx,eidx,str)))return -1; \ + SQInteger slen = _string(str)->_len; \ + if(sidx < 0)sidx = slen + sidx; \ + if(eidx < 0)eidx = slen + eidx; \ + if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes")); \ + if(eidx > slen || sidx < 0) return sq_throwerror(v,_SC("slice out of range")); \ + SQInteger len=_string(str)->_len; \ + const SQChar *sthis=_stringval(str); \ + SQChar *snew=(_ss(v)->GetScratchPad(sq_rsl(len))); \ + memcpy(snew,sthis,sq_rsl(len));\ + for(SQInteger i=sidx;iPush(SQString::Create(_ss(v),snew,len)); \ + return 1; \ +} + + +STRING_TOFUNCZ(tolower) +STRING_TOFUNCZ(toupper) + +const SQRegFunction SQSharedState::_string_default_delegate_funcz[]={ + {_SC("len"),default_delegate_len,1, _SC("s")}, + {_SC("tointeger"),default_delegate_tointeger,-1, _SC("sn")}, + {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")}, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("slice"),string_slice,-1, _SC("s n n")}, + {_SC("find"),string_find,-2, _SC("s s n")}, + {_SC("tolower"),string_tolower,-1, _SC("s n n")}, + {_SC("toupper"),string_toupper,-1, _SC("s n n")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {NULL,(SQFUNCTION)0,0,NULL} +}; + +//INTEGER DEFAULT DELEGATE////////////////////////// +const SQRegFunction SQSharedState::_number_default_delegate_funcz[]={ + {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")}, + {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")}, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {NULL,(SQFUNCTION)0,0,NULL} +}; + +//CLOSURE DEFAULT DELEGATE////////////////////////// +static SQInteger closure_pcall(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQFalse))?1:SQ_ERROR; +} + +static SQInteger closure_call(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQTrue))?1:SQ_ERROR; +} + +static SQInteger _closure_acall(HSQUIRRELVM v,SQBool raiseerror) +{ + SQArray *aparams=_array(stack_get(v,2)); + SQInteger nparams=aparams->Size(); + v->Push(stack_get(v,1)); + for(SQInteger i=0;iPush(aparams->_values[i]); + return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue,raiseerror))?1:SQ_ERROR; +} + +static SQInteger closure_acall(HSQUIRRELVM v) +{ + return _closure_acall(v,SQTrue); +} + +static SQInteger closure_pacall(HSQUIRRELVM v) +{ + return _closure_acall(v,SQFalse); +} + +static SQInteger closure_bindenv(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_bindenv(v,1))) + return SQ_ERROR; + return 1; +} + +static SQInteger closure_getroot(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_getclosureroot(v,-1))) + return SQ_ERROR; + return 1; +} + +static SQInteger closure_setroot(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_setclosureroot(v,-2))) + return SQ_ERROR; + return 1; +} + +static SQInteger closure_getinfos(HSQUIRRELVM v) { + SQObject o = stack_get(v,1); + SQTable *res = SQTable::Create(_ss(v),4); + if(type(o) == OT_CLOSURE) { + SQFunctionProto *f = _closure(o)->_function; + SQInteger nparams = f->_nparameters + (f->_varparams?1:0); + SQObjectPtr params = SQArray::Create(_ss(v),nparams); + SQObjectPtr defparams = SQArray::Create(_ss(v),f->_ndefaultparams); + for(SQInteger n = 0; n_nparameters; n++) { + _array(params)->Set((SQInteger)n,f->_parameters[n]); + } + for(SQInteger j = 0; j_ndefaultparams; j++) { + _array(defparams)->Set((SQInteger)j,_closure(o)->_defaultparams[j]); + } + if(f->_varparams) { + _array(params)->Set(nparams-1,SQString::Create(_ss(v),_SC("..."),-1)); + } + res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),false); + res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),f->_name); + res->NewSlot(SQString::Create(_ss(v),_SC("src"),-1),f->_sourcename); + res->NewSlot(SQString::Create(_ss(v),_SC("parameters"),-1),params); + res->NewSlot(SQString::Create(_ss(v),_SC("varargs"),-1),f->_varparams); + res->NewSlot(SQString::Create(_ss(v),_SC("defparams"),-1),defparams); + } + else { //OT_NATIVECLOSURE + SQNativeClosure *nc = _nativeclosure(o); + res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),true); + res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),nc->_name); + res->NewSlot(SQString::Create(_ss(v),_SC("paramscheck"),-1),nc->_nparamscheck); + SQObjectPtr typecheck; + if(nc->_typecheck.size() > 0) { + typecheck = + SQArray::Create(_ss(v), nc->_typecheck.size()); + for(SQUnsignedInteger n = 0; n_typecheck.size(); n++) { + _array(typecheck)->Set((SQInteger)n,nc->_typecheck[n]); + } + } + res->NewSlot(SQString::Create(_ss(v),_SC("typecheck"),-1),typecheck); + } + v->Push(res); + return 1; +} + + + +const SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={ + {_SC("call"),closure_call,-1, _SC("c")}, + {_SC("pcall"),closure_pcall,-1, _SC("c")}, + {_SC("acall"),closure_acall,2, _SC("ca")}, + {_SC("pacall"),closure_pacall,2, _SC("ca")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t")}, + {_SC("getinfos"),closure_getinfos,1, _SC("c")}, + {_SC("getroot"),closure_getroot,1, _SC("c")}, + {_SC("setroot"),closure_setroot,2, _SC("ct")}, + {NULL,(SQFUNCTION)0,0,NULL} +}; + +//GENERATOR DEFAULT DELEGATE +static SQInteger generator_getstatus(HSQUIRRELVM v) +{ + SQObject &o=stack_get(v,1); + switch(_generator(o)->_state){ + case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break; + case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break; + case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break; + } + return 1; +} + +const SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={ + {_SC("getstatus"),generator_getstatus,1, _SC("g")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {NULL,(SQFUNCTION)0,0,NULL} +}; + +//THREAD DEFAULT DELEGATE +static SQInteger thread_call(HSQUIRRELVM v) +{ + SQObjectPtr o = stack_get(v,1); + if(type(o) == OT_THREAD) { + SQInteger nparams = sq_gettop(v); + _thread(o)->Push(_thread(o)->_roottable); + for(SQInteger i = 2; i<(nparams+1); i++) + sq_move(_thread(o),v,i); + if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQTrue))) { + sq_move(v,_thread(o),-1); + sq_pop(_thread(o),1); + return 1; + } + v->_lasterror = _thread(o)->_lasterror; + return SQ_ERROR; + } + return sq_throwerror(v,_SC("wrong parameter")); +} + +static SQInteger thread_wakeup(HSQUIRRELVM v) +{ + SQObjectPtr o = stack_get(v,1); + if(type(o) == OT_THREAD) { + SQVM *thread = _thread(o); + SQInteger state = sq_getvmstate(thread); + if(state != SQ_VMSTATE_SUSPENDED) { + switch(state) { + case SQ_VMSTATE_IDLE: + return sq_throwerror(v,_SC("cannot wakeup a idle thread")); + break; + case SQ_VMSTATE_RUNNING: + return sq_throwerror(v,_SC("cannot wakeup a running thread")); + break; + } + } + + SQInteger wakeupret = sq_gettop(v)>1?SQTrue:SQFalse; + if(wakeupret) { + sq_move(thread,v,2); + } + if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,SQTrue,SQTrue,SQFalse))) { + sq_move(v,thread,-1); + sq_pop(thread,1); //pop retval + if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) { + sq_settop(thread,1); //pop roottable + } + return 1; + } + sq_settop(thread,1); + v->_lasterror = thread->_lasterror; + return SQ_ERROR; + } + return sq_throwerror(v,_SC("wrong parameter")); +} + +static SQInteger thread_wakeupthrow(HSQUIRRELVM v) +{ + SQObjectPtr o = stack_get(v,1); + if(type(o) == OT_THREAD) { + SQVM *thread = _thread(o); + SQInteger state = sq_getvmstate(thread); + if(state != SQ_VMSTATE_SUSPENDED) { + switch(state) { + case SQ_VMSTATE_IDLE: + return sq_throwerror(v,_SC("cannot wakeup a idle thread")); + break; + case SQ_VMSTATE_RUNNING: + return sq_throwerror(v,_SC("cannot wakeup a running thread")); + break; + } + } + + sq_move(thread,v,2); + sq_throwobject(thread); + SQBool rethrow_error = SQTrue; + if(sq_gettop(v) > 2) { + sq_getbool(v,3,&rethrow_error); + } + if(SQ_SUCCEEDED(sq_wakeupvm(thread,SQFalse,SQTrue,SQTrue,SQTrue))) { + sq_move(v,thread,-1); + sq_pop(thread,1); //pop retval + if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) { + sq_settop(thread,1); //pop roottable + } + return 1; + } + sq_settop(thread,1); + if(rethrow_error) { + v->_lasterror = thread->_lasterror; + return SQ_ERROR; + } + return SQ_OK; + } + return sq_throwerror(v,_SC("wrong parameter")); +} + +static SQInteger thread_getstatus(HSQUIRRELVM v) +{ + SQObjectPtr &o = stack_get(v,1); + switch(sq_getvmstate(_thread(o))) { + case SQ_VMSTATE_IDLE: + sq_pushstring(v,_SC("idle"),-1); + break; + case SQ_VMSTATE_RUNNING: + sq_pushstring(v,_SC("running"),-1); + break; + case SQ_VMSTATE_SUSPENDED: + sq_pushstring(v,_SC("suspended"),-1); + break; + default: + return sq_throwerror(v,_SC("internal VM error")); + } + return 1; +} + +static SQInteger thread_getstackinfos(HSQUIRRELVM v) +{ + SQObjectPtr o = stack_get(v,1); + if(type(o) == OT_THREAD) { + SQVM *thread = _thread(o); + SQInteger threadtop = sq_gettop(thread); + SQInteger level; + sq_getinteger(v,-1,&level); + SQRESULT res = __getcallstackinfos(thread,level); + if(SQ_FAILED(res)) + { + sq_settop(thread,threadtop); + if(type(thread->_lasterror) == OT_STRING) { + sq_throwerror(v,_stringval(thread->_lasterror)); + } + else { + sq_throwerror(v,_SC("unknown error")); + } + } + if(res > 0) { + //some result + sq_move(v,thread,-1); + sq_settop(thread,threadtop); + return 1; + } + //no result + sq_settop(thread,threadtop); + return 0; + + } + return sq_throwerror(v,_SC("wrong parameter")); +} + +const SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = { + {_SC("call"), thread_call, -1, _SC("v")}, + {_SC("wakeup"), thread_wakeup, -1, _SC("v")}, + {_SC("wakeupthrow"), thread_wakeupthrow, -2, _SC("v.b")}, + {_SC("getstatus"), thread_getstatus, 1, _SC("v")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("getstackinfos"),thread_getstackinfos,2, _SC("vn")}, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {NULL,(SQFUNCTION)0,0,NULL} +}; + +static SQInteger class_getattributes(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_getattributes(v,-2))?1:SQ_ERROR; +} + +static SQInteger class_setattributes(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_setattributes(v,-3))?1:SQ_ERROR; +} + +static SQInteger class_instance(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_createinstance(v,-1))?1:SQ_ERROR; +} + +static SQInteger class_getbase(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_getbase(v,-1))?1:SQ_ERROR; +} + +static SQInteger class_newmember(HSQUIRRELVM v) +{ + SQInteger top = sq_gettop(v); + SQBool bstatic = SQFalse; + if(top == 5) + { + sq_tobool(v,-1,&bstatic); + sq_pop(v,1); + } + + if(top < 4) { + sq_pushnull(v); + } + return SQ_SUCCEEDED(sq_newmember(v,-4,bstatic))?1:SQ_ERROR; +} + +static SQInteger class_rawnewmember(HSQUIRRELVM v) +{ + SQInteger top = sq_gettop(v); + SQBool bstatic = SQFalse; + if(top == 5) + { + sq_tobool(v,-1,&bstatic); + sq_pop(v,1); + } + + if(top < 4) { + sq_pushnull(v); + } + return SQ_SUCCEEDED(sq_rawnewmember(v,-4,bstatic))?1:SQ_ERROR; +} + +const SQRegFunction SQSharedState::_class_default_delegate_funcz[] = { + {_SC("getattributes"), class_getattributes, 2, _SC("y.")}, + {_SC("setattributes"), class_setattributes, 3, _SC("y..")}, + {_SC("rawget"),container_rawget,2, _SC("y")}, + {_SC("rawset"),container_rawset,3, _SC("y")}, + {_SC("rawin"),container_rawexists,2, _SC("y")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("instance"),class_instance,1, _SC("y")}, + {_SC("getbase"),class_getbase,1, _SC("y")}, + {_SC("newmember"),class_newmember,-3, _SC("y")}, + {_SC("rawnewmember"),class_rawnewmember,-3, _SC("y")}, + {NULL,(SQFUNCTION)0,0,NULL} +}; + + +static SQInteger instance_getclass(HSQUIRRELVM v) +{ + if(SQ_SUCCEEDED(sq_getclass(v,1))) + return 1; + return SQ_ERROR; +} + +const SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = { + {_SC("getclass"), instance_getclass, 1, _SC("x")}, + {_SC("rawget"),container_rawget,2, _SC("x")}, + {_SC("rawset"),container_rawset,3, _SC("x")}, + {_SC("rawin"),container_rawexists,2, _SC("x")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {NULL,(SQFUNCTION)0,0,NULL} +}; + +static SQInteger weakref_ref(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_getweakrefval(v,1))) + return SQ_ERROR; + return 1; +} + +const SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = { + {_SC("ref"),weakref_ref,1, _SC("r")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {NULL,(SQFUNCTION)0,0,NULL} +}; diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqclass.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqclass.cpp new file mode 100644 index 00000000000..9845b83a77a --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqclass.cpp @@ -0,0 +1,210 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqtable.h" +#include "sqclass.h" +#include "sqfuncproto.h" +#include "sqclosure.h" + + + +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); + + 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); + } +} + +SQClass::~SQClass() +{ + 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 = type(val) == OT_CLOSURE || 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((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) && + (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) { + _metamethods[mmidx] = val; + } + else { + SQObjectPtr theval = val; + if(_base && type(val) == OT_CLOSURE) { + theval = _closure(val)->Clone(); + _closure(theval)->_base = _base; + __ObjAddRef(_base); //ref for the closure + } + if(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(_opt_ss(this),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; +} + +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; +} + +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; +} + +/////////////////////////////////////////////////////////////////////// +void SQInstance::Init(SQSharedState *ss) +{ + _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); +} + +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); +} + +void SQInstance::Finalize() +{ + 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 +} + +bool SQInstance::GetMetaMethod(SQVM SQ_UNUSED_ARG(*v),SQMetaMethod mm,SQObjectPtr &res) +{ + if(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; +} diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqclass.h b/src/modules/app_sqlang/squirrel/squirrel/sqclass.h new file mode 100644 index 00000000000..23b4bcfd3f8 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqclass.h @@ -0,0 +1,162 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQCLASS_H_ +#define _SQCLASS_H_ + +struct SQInstance; + +struct SQClassMember { + SQObjectPtr val; + SQObjectPtr attrs; + void Null() { + val.Null(); + attrs.Null(); + } +}; + +typedef sqvector SQClassMemberVec; + +#define MEMBER_TYPE_METHOD 0x01000000 +#define MEMBER_TYPE_FIELD 0x02000000 + +#define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD) +#define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD) +#define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD|i)) +#define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD|i)) +#define _member_type(o) (_integer(o)&0xFF000000) +#define _member_idx(o) (_integer(o)&0x00FFFFFF) + +struct SQClass : public CHAINABLE_OBJ +{ + 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(); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable ** ); + SQObjectType GetType() {return OT_CLASS;} +#endif + 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)))) + +struct SQInstance : public SQDelegable +{ + 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) { + + 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(); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable ** ); + SQObjectType GetType() {return OT_INSTANCE;} +#endif + bool InstanceOf(SQClass *trg); + bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res); + + SQClass *_class; + SQUserPointer _userpointer; + SQRELEASEHOOK _hook; + SQInteger _memsize; + SQObjectPtr _values[1]; +}; + +#endif //_SQCLASS_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqclosure.h b/src/modules/app_sqlang/squirrel/squirrel/sqclosure.h new file mode 100644 index 00000000000..3e6c959b31e --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqclosure.h @@ -0,0 +1,201 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQCLOSURE_H_ +#define _SQCLOSURE_H_ + + +#define _CALC_CLOSURE_SIZE(func) (sizeof(SQClosure) + (func->_noutervalues*sizeof(SQObjectPtr)) + (func->_ndefaultparams*sizeof(SQObjectPtr))) + +struct SQFunctionProto; +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;} +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(_opt_ss(this),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); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize(){ + SQFunctionProto *f = _function; + _NULL_SQOBJECT_VECTOR(_outervalues,f->_noutervalues); + _NULL_SQOBJECT_VECTOR(_defaultparams,f->_ndefaultparams); + } + SQObjectType GetType() {return OT_CLOSURE;} +#endif + SQWeakRef *_env; + SQWeakRef *_root; + SQClass *_base; + SQFunctionProto *_function; + SQObjectPtr *_outervalues; + SQObjectPtr *_defaultparams; +}; + +////////////////////////////////////////////// +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); } + +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); } + + void Release() + { + this->~SQOuter(); + sq_vm_free(this,sizeof(SQOuter)); + } + +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize() { _value.Null(); } + SQObjectType GetType() {return OT_OUTER;} +#endif + + 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}; +private: + 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); + } + + bool Yield(SQVM *v,SQInteger target); + bool Resume(SQVM *v,SQObjectPtr &dest); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize(){_stack.resize(0);_closure.Null();} + SQObjectType GetType() {return OT_GENERATOR;} +#endif + SQObjectPtr _closure; + SQObjectPtrVec _stack; + SQVM::CallInfo _ci; + ExceptionsTraps _etraps; + SQGeneratorState _state; +}; + +#define _CALC_NATVIVECLOSURE_SIZE(noutervalues) (sizeof(SQNativeClosure) + (noutervalues*sizeof(SQObjectPtr))) + +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;} +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(_opt_ss(this),_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); + } + +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize() { _NULL_SQOBJECT_VECTOR(_outervalues,_noutervalues); } + SQObjectType GetType() {return OT_NATIVECLOSURE;} +#endif + SQInteger _nparamscheck; + SQIntVec _typecheck; + SQObjectPtr *_outervalues; + SQUnsignedInteger _noutervalues; + SQWeakRef *_env; + SQFUNCTION _function; + SQObjectPtr _name; +}; + + + +#endif //_SQCLOSURE_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqcompiler.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqcompiler.cpp new file mode 100644 index 00000000000..384a5e167e1 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqcompiler.cpp @@ -0,0 +1,1578 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#ifndef NO_COMPILER +#include +#include +#include "sqopcodes.h" +#include "sqstring.h" +#include "sqfuncproto.h" +#include "sqcompiler.h" +#include "sqfuncstate.h" +#include "sqlexer.h" +#include "sqvm.h" +#include "sqtable.h" + +#define EXPR 1 +#define OBJECT 2 +#define BASE 3 +#define LOCAL 4 +#define OUTER 5 + +struct SQExpState { + SQInteger etype; /* expr. type; one of EXPR, OBJECT, BASE, OUTER or LOCAL */ + SQInteger epos; /* expr. location on stack; -1 for OBJECT and BASE */ + bool donot_get; /* signal not to deref the next value */ +}; + +#define MAX_COMPILER_ERROR_LEN 256 + +struct SQScope { + SQInteger outers; + SQInteger stacksize; +}; + +#define BEGIN_SCOPE() SQScope __oldscope__ = _scope; \ + _scope.outers = _fs->_outers; \ + _scope.stacksize = _fs->GetStackSize(); + +#define RESOLVE_OUTERS() if(_fs->GetStackSize() != _scope.stacksize) { \ + if(_fs->CountOuters(_scope.stacksize)) { \ + _fs->AddInstruction(_OP_CLOSE,0,_scope.stacksize); \ + } \ + } + +#define END_SCOPE_NO_CLOSE() { if(_fs->GetStackSize() != _scope.stacksize) { \ + _fs->SetStackSize(_scope.stacksize); \ + } \ + _scope = __oldscope__; \ + } + +#define END_SCOPE() { SQInteger oldouters = _fs->_outers;\ + if(_fs->GetStackSize() != _scope.stacksize) { \ + _fs->SetStackSize(_scope.stacksize); \ + if(oldouters != _fs->_outers) { \ + _fs->AddInstruction(_OP_CLOSE,0,_scope.stacksize); \ + } \ + } \ + _scope = __oldscope__; \ + } + +#define BEGIN_BREAKBLE_BLOCK() SQInteger __nbreaks__=_fs->_unresolvedbreaks.size(); \ + SQInteger __ncontinues__=_fs->_unresolvedcontinues.size(); \ + _fs->_breaktargets.push_back(0);_fs->_continuetargets.push_back(0); + +#define END_BREAKBLE_BLOCK(continue_target) {__nbreaks__=_fs->_unresolvedbreaks.size()-__nbreaks__; \ + __ncontinues__=_fs->_unresolvedcontinues.size()-__ncontinues__; \ + if(__ncontinues__>0)ResolveContinues(_fs,__ncontinues__,continue_target); \ + if(__nbreaks__>0)ResolveBreaks(_fs,__nbreaks__); \ + _fs->_breaktargets.pop_back();_fs->_continuetargets.pop_back();} + +class SQCompiler +{ +public: + SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo) + { + _vm=v; + _lex.Init(_ss(v), rg, up,ThrowError,this); + _sourcename = SQString::Create(_ss(v), sourcename); + _lineinfo = lineinfo;_raiseerror = raiseerror; + _scope.outers = 0; + _scope.stacksize = 0; + _compilererror[0] = _SC('\0'); + } + static void ThrowError(void *ud, const SQChar *s) { + SQCompiler *c = (SQCompiler *)ud; + c->Error(s); + } + void Error(const SQChar *s, ...) + { + va_list vl; + va_start(vl, s); + scvsprintf(_compilererror, MAX_COMPILER_ERROR_LEN, s, vl); + va_end(vl); + longjmp(_errorjmp,1); + } + void Lex(){ _token = _lex.Lex();} + SQObject Expect(SQInteger tok) + { + + if(_token != tok) { + if(_token == TK_CONSTRUCTOR && tok == TK_IDENTIFIER) { + //do nothing + } + else { + const SQChar *etypename; + if(tok > 255) { + switch(tok) + { + case TK_IDENTIFIER: + etypename = _SC("IDENTIFIER"); + break; + case TK_STRING_LITERAL: + etypename = _SC("STRING_LITERAL"); + break; + case TK_INTEGER: + etypename = _SC("INTEGER"); + break; + case TK_FLOAT: + etypename = _SC("FLOAT"); + break; + default: + etypename = _lex.Tok2Str(tok); + } + Error(_SC("expected '%s'"), etypename); + } + Error(_SC("expected '%c'"), tok); + } + } + SQObjectPtr ret; + switch(tok) + { + case TK_IDENTIFIER: + ret = _fs->CreateString(_lex._svalue); + break; + case TK_STRING_LITERAL: + ret = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1); + break; + case TK_INTEGER: + ret = SQObjectPtr(_lex._nvalue); + break; + case TK_FLOAT: + ret = SQObjectPtr(_lex._fvalue); + break; + } + Lex(); + return ret; + } + bool IsEndOfStatement() { return ((_lex._prevtoken == _SC('\n')) || (_token == SQUIRREL_EOB) || (_token == _SC('}')) || (_token == _SC(';'))); } + void OptionalSemicolon() + { + if(_token == _SC(';')) { Lex(); return; } + if(!IsEndOfStatement()) { + Error(_SC("end of statement expected (; or lf)")); + } + } + void MoveIfCurrentTargetIsLocal() { + SQInteger trg = _fs->TopTarget(); + if(_fs->IsLocal(trg)) { + trg = _fs->PopTarget(); //pops the target and moves it + _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), trg); + } + } + bool Compile(SQObjectPtr &o) + { + _debugline = 1; + _debugop = 0; + + SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this); + funcstate._name = SQString::Create(_ss(_vm), _SC("main")); + _fs = &funcstate; + _fs->AddParameter(_fs->CreateString(_SC("this"))); + _fs->AddParameter(_fs->CreateString(_SC("vargv"))); + _fs->_varparams = true; + _fs->_sourcename = _sourcename; + SQInteger stacksize = _fs->GetStackSize(); + if(setjmp(_errorjmp) == 0) { + Lex(); + while(_token > 0){ + Statement(); + if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon(); + } + _fs->SetStackSize(stacksize); + _fs->AddLineInfos(_lex._currentline, _lineinfo, true); + _fs->AddInstruction(_OP_RETURN, 0xFF); + _fs->SetStackSize(0); + o =_fs->BuildProto(); +#ifdef _DEBUG_DUMP + _fs->Dump(_funcproto(o)); +#endif + } + else { + if(_raiseerror && _ss(_vm)->_compilererrorhandler) { + _ss(_vm)->_compilererrorhandler(_vm, _compilererror, type(_sourcename) == OT_STRING?_stringval(_sourcename):_SC("unknown"), + _lex._currentline, _lex._currentcolumn); + } + _vm->_lasterror = SQString::Create(_ss(_vm), _compilererror, -1); + return false; + } + return true; + } + void Statements() + { + while(_token != _SC('}') && _token != TK_DEFAULT && _token != TK_CASE) { + Statement(); + if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon(); + } + } + void Statement(bool closeframe = true) + { + _fs->AddLineInfos(_lex._currentline, _lineinfo); + switch(_token){ + case _SC(';'): Lex(); break; + case TK_IF: IfStatement(); break; + case TK_WHILE: WhileStatement(); break; + case TK_DO: DoWhileStatement(); break; + case TK_FOR: ForStatement(); break; + case TK_FOREACH: ForEachStatement(); break; + case TK_SWITCH: SwitchStatement(); break; + case TK_LOCAL: LocalDeclStatement(); break; + case TK_RETURN: + case TK_YIELD: { + SQOpcode op; + if(_token == TK_RETURN) { + op = _OP_RETURN; + } + else { + op = _OP_YIELD; + _fs->_bgenerator = true; + } + Lex(); + if(!IsEndOfStatement()) { + SQInteger retexp = _fs->GetCurrentPos()+1; + CommaExpr(); + if(op == _OP_RETURN && _fs->_traps > 0) + _fs->AddInstruction(_OP_POPTRAP, _fs->_traps, 0); + _fs->_returnexp = retexp; + _fs->AddInstruction(op, 1, _fs->PopTarget(),_fs->GetStackSize()); + } + else{ + if(op == _OP_RETURN && _fs->_traps > 0) + _fs->AddInstruction(_OP_POPTRAP, _fs->_traps ,0); + _fs->_returnexp = -1; + _fs->AddInstruction(op, 0xFF,0,_fs->GetStackSize()); + } + break;} + case TK_BREAK: + if(_fs->_breaktargets.size() <= 0)Error(_SC("'break' has to be in a loop block")); + if(_fs->_breaktargets.top() > 0){ + _fs->AddInstruction(_OP_POPTRAP, _fs->_breaktargets.top(), 0); + } + RESOLVE_OUTERS(); + _fs->AddInstruction(_OP_JMP, 0, -1234); + _fs->_unresolvedbreaks.push_back(_fs->GetCurrentPos()); + Lex(); + break; + case TK_CONTINUE: + if(_fs->_continuetargets.size() <= 0)Error(_SC("'continue' has to be in a loop block")); + if(_fs->_continuetargets.top() > 0) { + _fs->AddInstruction(_OP_POPTRAP, _fs->_continuetargets.top(), 0); + } + RESOLVE_OUTERS(); + _fs->AddInstruction(_OP_JMP, 0, -1234); + _fs->_unresolvedcontinues.push_back(_fs->GetCurrentPos()); + Lex(); + break; + case TK_FUNCTION: + FunctionStatement(); + break; + case TK_CLASS: + ClassStatement(); + break; + case TK_ENUM: + EnumStatement(); + break; + case _SC('{'):{ + BEGIN_SCOPE(); + Lex(); + Statements(); + Expect(_SC('}')); + if(closeframe) { + END_SCOPE(); + } + else { + END_SCOPE_NO_CLOSE(); + } + } + break; + case TK_TRY: + TryCatchStatement(); + break; + case TK_THROW: + Lex(); + CommaExpr(); + _fs->AddInstruction(_OP_THROW, _fs->PopTarget()); + break; + case TK_CONST: + { + Lex(); + SQObject id = Expect(TK_IDENTIFIER); + Expect('='); + SQObject val = ExpectScalar(); + OptionalSemicolon(); + SQTable *enums = _table(_ss(_vm)->_consts); + SQObjectPtr strongid = id; + enums->NewSlot(strongid,SQObjectPtr(val)); + strongid.Null(); + } + break; + default: + CommaExpr(); + _fs->DiscardTarget(); + //_fs->PopTarget(); + break; + } + _fs->SnoozeOpt(); + } + void EmitDerefOp(SQOpcode op) + { + SQInteger val = _fs->PopTarget(); + SQInteger key = _fs->PopTarget(); + SQInteger src = _fs->PopTarget(); + _fs->AddInstruction(op,_fs->PushTarget(),src,key,val); + } + void Emit2ArgsOP(SQOpcode op, SQInteger p3 = 0) + { + SQInteger p2 = _fs->PopTarget(); //src in OP_GET + SQInteger p1 = _fs->PopTarget(); //key in OP_GET + _fs->AddInstruction(op,_fs->PushTarget(), p1, p2, p3); + } + void EmitCompoundArith(SQInteger tok, SQInteger etype, SQInteger pos) + { + /* Generate code depending on the expression type */ + switch(etype) { + case LOCAL:{ + SQInteger p2 = _fs->PopTarget(); //src in OP_GET + SQInteger p1 = _fs->PopTarget(); //key in OP_GET + _fs->PushTarget(p1); + //EmitCompArithLocal(tok, p1, p1, p2); + _fs->AddInstruction(ChooseArithOpByToken(tok),p1, p2, p1, 0); + _fs->SnoozeOpt(); + } + break; + case OBJECT: + case BASE: + { + SQInteger val = _fs->PopTarget(); + SQInteger key = _fs->PopTarget(); + SQInteger src = _fs->PopTarget(); + /* _OP_COMPARITH mixes dest obj and source val in the arg1 */ + _fs->AddInstruction(_OP_COMPARITH, _fs->PushTarget(), (src<<16)|val, key, ChooseCompArithCharByToken(tok)); + } + break; + case OUTER: + { + SQInteger val = _fs->TopTarget(); + SQInteger tmp = _fs->PushTarget(); + _fs->AddInstruction(_OP_GETOUTER, tmp, pos); + _fs->AddInstruction(ChooseArithOpByToken(tok), tmp, val, tmp, 0); + _fs->PopTarget(); + _fs->PopTarget(); + _fs->AddInstruction(_OP_SETOUTER, _fs->PushTarget(), pos, tmp); + } + break; + } + } + void CommaExpr() + { + for(Expression();_token == ',';_fs->PopTarget(), Lex(), CommaExpr()); + } + void Expression() + { + SQExpState es = _es; + _es.etype = EXPR; + _es.epos = -1; + _es.donot_get = false; + LogicalOrExp(); + switch(_token) { + case _SC('='): + case TK_NEWSLOT: + case TK_MINUSEQ: + case TK_PLUSEQ: + case TK_MULEQ: + case TK_DIVEQ: + case TK_MODEQ:{ + SQInteger op = _token; + SQInteger ds = _es.etype; + SQInteger pos = _es.epos; + if(ds == EXPR) Error(_SC("can't assign expression")); + else if(ds == BASE) Error(_SC("'base' cannot be modified")); + Lex(); Expression(); + + switch(op){ + case TK_NEWSLOT: + if(ds == OBJECT || ds == BASE) + EmitDerefOp(_OP_NEWSLOT); + else //if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local + Error(_SC("can't 'create' a local slot")); + break; + case _SC('='): //ASSIGN + switch(ds) { + case LOCAL: + { + SQInteger src = _fs->PopTarget(); + SQInteger dst = _fs->TopTarget(); + _fs->AddInstruction(_OP_MOVE, dst, src); + } + break; + case OBJECT: + case BASE: + EmitDerefOp(_OP_SET); + break; + case OUTER: + { + SQInteger src = _fs->PopTarget(); + SQInteger dst = _fs->PushTarget(); + _fs->AddInstruction(_OP_SETOUTER, dst, pos, src); + } + } + break; + case TK_MINUSEQ: + case TK_PLUSEQ: + case TK_MULEQ: + case TK_DIVEQ: + case TK_MODEQ: + EmitCompoundArith(op, ds, pos); + break; + } + } + break; + case _SC('?'): { + Lex(); + _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); + SQInteger jzpos = _fs->GetCurrentPos(); + SQInteger trg = _fs->PushTarget(); + Expression(); + SQInteger first_exp = _fs->PopTarget(); + if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp); + SQInteger endfirstexp = _fs->GetCurrentPos(); + _fs->AddInstruction(_OP_JMP, 0, 0); + Expect(_SC(':')); + SQInteger jmppos = _fs->GetCurrentPos(); + Expression(); + SQInteger second_exp = _fs->PopTarget(); + if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); + _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos); + _fs->SetIntructionParam(jzpos, 1, endfirstexp - jzpos + 1); + _fs->SnoozeOpt(); + } + break; + } + _es = es; + } + template void INVOKE_EXP(T f) + { + SQExpState es = _es; + _es.etype = EXPR; + _es.epos = -1; + _es.donot_get = false; + (this->*f)(); + _es = es; + } + template void BIN_EXP(SQOpcode op, T f,SQInteger op3 = 0) + { + Lex(); + INVOKE_EXP(f); + SQInteger op1 = _fs->PopTarget();SQInteger op2 = _fs->PopTarget(); + _fs->AddInstruction(op, _fs->PushTarget(), op1, op2, op3); + } + void LogicalOrExp() + { + LogicalAndExp(); + for(;;) if(_token == TK_OR) { + SQInteger first_exp = _fs->PopTarget(); + SQInteger trg = _fs->PushTarget(); + _fs->AddInstruction(_OP_OR, trg, 0, first_exp, 0); + SQInteger jpos = _fs->GetCurrentPos(); + if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp); + Lex(); INVOKE_EXP(&SQCompiler::LogicalOrExp); + _fs->SnoozeOpt(); + SQInteger second_exp = _fs->PopTarget(); + if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); + _fs->SnoozeOpt(); + _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos)); + break; + }else return; + } + void LogicalAndExp() + { + BitwiseOrExp(); + for(;;) switch(_token) { + case TK_AND: { + SQInteger first_exp = _fs->PopTarget(); + SQInteger trg = _fs->PushTarget(); + _fs->AddInstruction(_OP_AND, trg, 0, first_exp, 0); + SQInteger jpos = _fs->GetCurrentPos(); + if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp); + Lex(); INVOKE_EXP(&SQCompiler::LogicalAndExp); + _fs->SnoozeOpt(); + SQInteger second_exp = _fs->PopTarget(); + if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); + _fs->SnoozeOpt(); + _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos)); + break; + } + + default: + return; + } + } + void BitwiseOrExp() + { + BitwiseXorExp(); + for(;;) if(_token == _SC('|')) + {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseXorExp,BW_OR); + }else return; + } + void BitwiseXorExp() + { + BitwiseAndExp(); + for(;;) if(_token == _SC('^')) + {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseAndExp,BW_XOR); + }else return; + } + void BitwiseAndExp() + { + EqExp(); + for(;;) if(_token == _SC('&')) + {BIN_EXP(_OP_BITW, &SQCompiler::EqExp,BW_AND); + }else return; + } + void EqExp() + { + CompExp(); + for(;;) switch(_token) { + case TK_EQ: BIN_EXP(_OP_EQ, &SQCompiler::CompExp); break; + case TK_NE: BIN_EXP(_OP_NE, &SQCompiler::CompExp); break; + case TK_3WAYSCMP: BIN_EXP(_OP_CMP, &SQCompiler::CompExp,CMP_3W); break; + default: return; + } + } + void CompExp() + { + ShiftExp(); + for(;;) switch(_token) { + case _SC('>'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_G); break; + case _SC('<'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_L); break; + case TK_GE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_GE); break; + case TK_LE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_LE); break; + case TK_IN: BIN_EXP(_OP_EXISTS, &SQCompiler::ShiftExp); break; + case TK_INSTANCEOF: BIN_EXP(_OP_INSTANCEOF, &SQCompiler::ShiftExp); break; + default: return; + } + } + void ShiftExp() + { + PlusExp(); + for(;;) switch(_token) { + case TK_USHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_USHIFTR); break; + case TK_SHIFTL: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTL); break; + case TK_SHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTR); break; + default: return; + } + } + SQOpcode ChooseArithOpByToken(SQInteger tok) + { + switch(tok) { + case TK_PLUSEQ: case '+': return _OP_ADD; + case TK_MINUSEQ: case '-': return _OP_SUB; + case TK_MULEQ: case '*': return _OP_MUL; + case TK_DIVEQ: case '/': return _OP_DIV; + case TK_MODEQ: case '%': return _OP_MOD; + default: assert(0); + } + return _OP_ADD; + } + SQInteger ChooseCompArithCharByToken(SQInteger tok) + { + SQInteger oper; + switch(tok){ + case TK_MINUSEQ: oper = '-'; break; + case TK_PLUSEQ: oper = '+'; break; + case TK_MULEQ: oper = '*'; break; + case TK_DIVEQ: oper = '/'; break; + case TK_MODEQ: oper = '%'; break; + default: oper = 0; //shut up compiler + assert(0); break; + }; + return oper; + } + void PlusExp() + { + MultExp(); + for(;;) switch(_token) { + case _SC('+'): case _SC('-'): + BIN_EXP(ChooseArithOpByToken(_token), &SQCompiler::MultExp); break; + default: return; + } + } + + void MultExp() + { + PrefixedExpr(); + for(;;) switch(_token) { + case _SC('*'): case _SC('/'): case _SC('%'): + BIN_EXP(ChooseArithOpByToken(_token), &SQCompiler::PrefixedExpr); break; + default: return; + } + } + //if 'pos' != -1 the previous variable is a local variable + void PrefixedExpr() + { + SQInteger pos = Factor(); + for(;;) { + switch(_token) { + case _SC('.'): + pos = -1; + Lex(); + + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER))); + if(_es.etype==BASE) { + Emit2ArgsOP(_OP_GET); + pos = _fs->TopTarget(); + _es.etype = EXPR; + _es.epos = pos; + } + else { + if(NeedGet()) { + Emit2ArgsOP(_OP_GET); + } + _es.etype = OBJECT; + } + break; + case _SC('['): + if(_lex._prevtoken == _SC('\n')) Error(_SC("cannot brake deref/or comma needed after [exp]=exp slot declaration")); + Lex(); Expression(); Expect(_SC(']')); + pos = -1; + if(_es.etype==BASE) { + Emit2ArgsOP(_OP_GET); + pos = _fs->TopTarget(); + _es.etype = EXPR; + _es.epos = pos; + } + else { + if(NeedGet()) { + Emit2ArgsOP(_OP_GET); + } + _es.etype = OBJECT; + } + break; + case TK_MINUSMINUS: + case TK_PLUSPLUS: + { + if(IsEndOfStatement()) return; + SQInteger diff = (_token==TK_MINUSMINUS) ? -1 : 1; + Lex(); + switch(_es.etype) + { + case EXPR: Error(_SC("can't '++' or '--' an expression")); break; + case OBJECT: + case BASE: + if(_es.donot_get == true) { Error(_SC("can't '++' or '--' an expression")); break; } //mmh dor this make sense? + Emit2ArgsOP(_OP_PINC, diff); + break; + case LOCAL: { + SQInteger src = _fs->PopTarget(); + _fs->AddInstruction(_OP_PINCL, _fs->PushTarget(), src, 0, diff); + } + break; + case OUTER: { + SQInteger tmp1 = _fs->PushTarget(); + SQInteger tmp2 = _fs->PushTarget(); + _fs->AddInstruction(_OP_GETOUTER, tmp2, _es.epos); + _fs->AddInstruction(_OP_PINCL, tmp1, tmp2, 0, diff); + _fs->AddInstruction(_OP_SETOUTER, tmp2, _es.epos, tmp2); + _fs->PopTarget(); + } + } + } + return; + break; + case _SC('('): + switch(_es.etype) { + case OBJECT: { + SQInteger key = _fs->PopTarget(); /* location of the key */ + SQInteger table = _fs->PopTarget(); /* location of the object */ + SQInteger closure = _fs->PushTarget(); /* location for the closure */ + SQInteger ttarget = _fs->PushTarget(); /* location for 'this' pointer */ + _fs->AddInstruction(_OP_PREPCALL, closure, key, table, ttarget); + } + break; + case BASE: + //Emit2ArgsOP(_OP_GET); + _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0); + break; + case OUTER: + _fs->AddInstruction(_OP_GETOUTER, _fs->PushTarget(), _es.epos); + _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0); + break; + default: + _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0); + } + _es.etype = EXPR; + Lex(); + FunctionCallArgs(); + break; + default: return; + } + } + } + SQInteger Factor() + { + //_es.etype = EXPR; + switch(_token) + { + case TK_STRING_LITERAL: + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_fs->CreateString(_lex._svalue,_lex._longstr.size()-1))); + Lex(); + break; + case TK_BASE: + Lex(); + _fs->AddInstruction(_OP_GETBASE, _fs->PushTarget()); + _es.etype = BASE; + _es.epos = _fs->TopTarget(); + return (_es.epos); + break; + case TK_IDENTIFIER: + case TK_CONSTRUCTOR: + case TK_THIS:{ + SQObject id; + SQObject constant; + + switch(_token) { + case TK_IDENTIFIER: id = _fs->CreateString(_lex._svalue); break; + case TK_THIS: id = _fs->CreateString(_SC("this"),4); break; + case TK_CONSTRUCTOR: id = _fs->CreateString(_SC("constructor"),11); break; + } + + SQInteger pos = -1; + Lex(); + if((pos = _fs->GetLocalVariable(id)) != -1) { + /* Handle a local variable (includes 'this') */ + _fs->PushTarget(pos); + _es.etype = LOCAL; + _es.epos = pos; + } + + else if((pos = _fs->GetOuterVariable(id)) != -1) { + /* Handle a free var */ + if(NeedGet()) { + _es.epos = _fs->PushTarget(); + _fs->AddInstruction(_OP_GETOUTER, _es.epos, pos); + /* _es.etype = EXPR; already default value */ + } + else { + _es.etype = OUTER; + _es.epos = pos; + } + } + + else if(_fs->IsConstant(id, constant)) { + /* Handle named constant */ + SQObjectPtr constval; + SQObject constid; + if(type(constant) == OT_TABLE) { + Expect('.'); + constid = Expect(TK_IDENTIFIER); + if(!_table(constant)->Get(constid, constval)) { + constval.Null(); + Error(_SC("invalid constant [%s.%s]"), _stringval(id), _stringval(constid)); + } + } + else { + constval = constant; + } + _es.epos = _fs->PushTarget(); + + /* generate direct or literal function depending on size */ + SQObjectType ctype = type(constval); + switch(ctype) { + case OT_INTEGER: EmitLoadConstInt(_integer(constval),_es.epos); break; + case OT_FLOAT: EmitLoadConstFloat(_float(constval),_es.epos); break; + case OT_BOOL: _fs->AddInstruction(_OP_LOADBOOL, _es.epos, _integer(constval)); break; + default: _fs->AddInstruction(_OP_LOAD,_es.epos,_fs->GetConstant(constval)); break; + } + _es.etype = EXPR; + } + else { + /* Handle a non-local variable, aka a field. Push the 'this' pointer on + * the virtual stack (always found in offset 0, so no instruction needs to + * be generated), and push the key next. Generate an _OP_LOAD instruction + * for the latter. If we are not using the variable as a dref expr, generate + * the _OP_GET instruction. + */ + _fs->PushTarget(0); + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); + if(NeedGet()) { + Emit2ArgsOP(_OP_GET); + } + _es.etype = OBJECT; + } + return _es.epos; + } + break; + case TK_DOUBLE_COLON: // "::" + _fs->AddInstruction(_OP_LOADROOT, _fs->PushTarget()); + _es.etype = OBJECT; + _token = _SC('.'); /* hack: drop into PrefixExpr, case '.'*/ + _es.epos = -1; + return _es.epos; + break; + case TK_NULL: + _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1); + Lex(); + break; + case TK_INTEGER: EmitLoadConstInt(_lex._nvalue,-1); Lex(); break; + case TK_FLOAT: EmitLoadConstFloat(_lex._fvalue,-1); Lex(); break; + case TK_TRUE: case TK_FALSE: + _fs->AddInstruction(_OP_LOADBOOL, _fs->PushTarget(),_token == TK_TRUE?1:0); + Lex(); + break; + case _SC('['): { + _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,0,NOT_ARRAY); + SQInteger apos = _fs->GetCurrentPos(),key = 0; + Lex(); + while(_token != _SC(']')) { + Expression(); + if(_token == _SC(',')) Lex(); + SQInteger val = _fs->PopTarget(); + SQInteger array = _fs->TopTarget(); + _fs->AddInstruction(_OP_APPENDARRAY, array, val, AAT_STACK); + key++; + } + _fs->SetIntructionParam(apos, 1, key); + Lex(); + } + break; + case _SC('{'): + _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE); + Lex();ParseTableOrClass(_SC(','),_SC('}')); + break; + case TK_FUNCTION: FunctionExp(_token);break; + case _SC('@'): FunctionExp(_token,true);break; + case TK_CLASS: Lex(); ClassExp();break; + case _SC('-'): + Lex(); + switch(_token) { + case TK_INTEGER: EmitLoadConstInt(-_lex._nvalue,-1); Lex(); break; + case TK_FLOAT: EmitLoadConstFloat(-_lex._fvalue,-1); Lex(); break; + default: UnaryOP(_OP_NEG); + } + break; + case _SC('!'): Lex(); UnaryOP(_OP_NOT); break; + case _SC('~'): + Lex(); + if(_token == TK_INTEGER) { EmitLoadConstInt(~_lex._nvalue,-1); Lex(); break; } + UnaryOP(_OP_BWNOT); + break; + case TK_TYPEOF : Lex() ;UnaryOP(_OP_TYPEOF); break; + case TK_RESUME : Lex(); UnaryOP(_OP_RESUME); break; + case TK_CLONE : Lex(); UnaryOP(_OP_CLONE); break; + case TK_MINUSMINUS : + case TK_PLUSPLUS :PrefixIncDec(_token); break; + case TK_DELETE : DeleteExpr(); break; + case _SC('('): Lex(); CommaExpr(); Expect(_SC(')')); + break; + case TK___LINE__: EmitLoadConstInt(_lex._currentline,-1); Lex(); break; + case TK___FILE__: _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_sourcename)); Lex(); break; + default: Error(_SC("expression expected")); + } + _es.etype = EXPR; + return -1; + } + void EmitLoadConstInt(SQInteger value,SQInteger target) + { + if(target < 0) { + target = _fs->PushTarget(); + } + if(value <= INT_MAX && value > INT_MIN) { //does it fit in 32 bits? + _fs->AddInstruction(_OP_LOADINT, target,value); + } + else { + _fs->AddInstruction(_OP_LOAD, target, _fs->GetNumericConstant(value)); + } + } + void EmitLoadConstFloat(SQFloat value,SQInteger target) + { + if(target < 0) { + target = _fs->PushTarget(); + } + if(sizeof(SQFloat) == sizeof(SQInt32)) { + _fs->AddInstruction(_OP_LOADFLOAT, target,*((SQInt32 *)&value)); + } + else { + _fs->AddInstruction(_OP_LOAD, target, _fs->GetNumericConstant(value)); + } + } + void UnaryOP(SQOpcode op) + { + PrefixedExpr(); + SQInteger src = _fs->PopTarget(); + _fs->AddInstruction(op, _fs->PushTarget(), src); + } + bool NeedGet() + { + switch(_token) { + case _SC('='): case _SC('('): case TK_NEWSLOT: case TK_MODEQ: case TK_MULEQ: + case TK_DIVEQ: case TK_MINUSEQ: case TK_PLUSEQ: + return false; + case TK_PLUSPLUS: case TK_MINUSMINUS: + if (!IsEndOfStatement()) { + return false; + } + break; + } + return (!_es.donot_get || ( _es.donot_get && (_token == _SC('.') || _token == _SC('[')))); + } + void FunctionCallArgs() + { + SQInteger nargs = 1;//this + while(_token != _SC(')')) { + Expression(); + MoveIfCurrentTargetIsLocal(); + nargs++; + if(_token == _SC(',')){ + Lex(); + if(_token == ')') Error(_SC("expression expected, found ')'")); + } + } + Lex(); + for(SQInteger i = 0; i < (nargs - 1); i++) _fs->PopTarget(); + SQInteger stackbase = _fs->PopTarget(); + SQInteger closure = _fs->PopTarget(); + _fs->AddInstruction(_OP_CALL, _fs->PushTarget(), closure, stackbase, nargs); + } + void ParseTableOrClass(SQInteger separator,SQInteger terminator) + { + SQInteger tpos = _fs->GetCurrentPos(),nkeys = 0; + while(_token != terminator) { + bool hasattrs = false; + bool isstatic = false; + //check if is an attribute + if(separator == ';') { + if(_token == TK_ATTR_OPEN) { + _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE); Lex(); + ParseTableOrClass(',',TK_ATTR_CLOSE); + hasattrs = true; + } + if(_token == TK_STATIC) { + isstatic = true; + Lex(); + } + } + switch(_token) { + case TK_FUNCTION: + case TK_CONSTRUCTOR:{ + SQInteger tk = _token; + Lex(); + SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor")); + Expect(_SC('(')); + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); + CreateFunction(id); + _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0); + } + break; + case _SC('['): + Lex(); CommaExpr(); Expect(_SC(']')); + Expect(_SC('=')); Expression(); + break; + case TK_STRING_LITERAL: //JSON + if(separator == ',') { //only works for tables + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_STRING_LITERAL))); + Expect(_SC(':')); Expression(); + break; + } + default : + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER))); + Expect(_SC('=')); Expression(); + } + if(_token == separator) Lex();//optional comma/semicolon + nkeys++; + SQInteger val = _fs->PopTarget(); + SQInteger key = _fs->PopTarget(); + SQInteger attrs = hasattrs ? _fs->PopTarget():-1; + ((void)attrs); + assert((hasattrs && (attrs == key-1)) || !hasattrs); + unsigned char flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0); + SQInteger table = _fs->TopTarget(); //<AddInstruction(_OP_NEWSLOT, 0xFF, table, key, val); + } + else { + _fs->AddInstruction(_OP_NEWSLOTA, flags, table, key, val); //this for classes only as it invokes _newmember + } + } + if(separator == _SC(',')) //hack recognizes a table from the separator + _fs->SetIntructionParam(tpos, 1, nkeys); + Lex(); + } + void LocalDeclStatement() + { + SQObject varname; + Lex(); + if( _token == TK_FUNCTION) { + Lex(); + varname = Expect(TK_IDENTIFIER); + Expect(_SC('(')); + CreateFunction(varname,false); + _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0); + _fs->PopTarget(); + _fs->PushLocalVariable(varname); + return; + } + + do { + varname = Expect(TK_IDENTIFIER); + if(_token == _SC('=')) { + Lex(); Expression(); + SQInteger src = _fs->PopTarget(); + SQInteger dest = _fs->PushTarget(); + if(dest != src) _fs->AddInstruction(_OP_MOVE, dest, src); + } + else{ + _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1); + } + _fs->PopTarget(); + _fs->PushLocalVariable(varname); + if(_token == _SC(',')) Lex(); else break; + } while(1); + } + void IfBlock() + { + if (_token == _SC('{')) + { + BEGIN_SCOPE(); + Lex(); + Statements(); + Expect(_SC('}')); + if (true) { + END_SCOPE(); + } + else { + END_SCOPE_NO_CLOSE(); + } + } + else { + //BEGIN_SCOPE(); + Statement(); + if (_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon(); + //END_SCOPE(); + } + } + void IfStatement() + { + SQInteger jmppos; + bool haselse = false; + Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); + _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); + SQInteger jnepos = _fs->GetCurrentPos(); + + + + IfBlock(); + // + /*static int n = 0; + if (_token != _SC('}') && _token != TK_ELSE) { + printf("IF %d-----------------------!!!!!!!!!\n", n); + if (n == 5) + { + printf("asd"); + } + n++; + //OptionalSemicolon(); + }*/ + + + SQInteger endifblock = _fs->GetCurrentPos(); + if(_token == TK_ELSE){ + haselse = true; + //BEGIN_SCOPE(); + _fs->AddInstruction(_OP_JMP); + jmppos = _fs->GetCurrentPos(); + Lex(); + //Statement(); if(_lex._prevtoken != _SC('}')) OptionalSemicolon(); + IfBlock(); + //END_SCOPE(); + _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos); + } + _fs->SetIntructionParam(jnepos, 1, endifblock - jnepos + (haselse?1:0)); + } + void WhileStatement() + { + SQInteger jzpos, jmppos; + jmppos = _fs->GetCurrentPos(); + Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); + + BEGIN_BREAKBLE_BLOCK(); + _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); + jzpos = _fs->GetCurrentPos(); + BEGIN_SCOPE(); + + Statement(); + + END_SCOPE(); + _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1); + _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos); + + END_BREAKBLE_BLOCK(jmppos); + } + void DoWhileStatement() + { + Lex(); + SQInteger jmptrg = _fs->GetCurrentPos(); + BEGIN_BREAKBLE_BLOCK() + BEGIN_SCOPE(); + Statement(); + END_SCOPE(); + Expect(TK_WHILE); + SQInteger continuetrg = _fs->GetCurrentPos(); + Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); + _fs->AddInstruction(_OP_JZ, _fs->PopTarget(), 1); + _fs->AddInstruction(_OP_JMP, 0, jmptrg - _fs->GetCurrentPos() - 1); + END_BREAKBLE_BLOCK(continuetrg); + } + void ForStatement() + { + Lex(); + BEGIN_SCOPE(); + Expect(_SC('(')); + if(_token == TK_LOCAL) LocalDeclStatement(); + else if(_token != _SC(';')){ + CommaExpr(); + _fs->PopTarget(); + } + Expect(_SC(';')); + _fs->SnoozeOpt(); + SQInteger jmppos = _fs->GetCurrentPos(); + SQInteger jzpos = -1; + if(_token != _SC(';')) { CommaExpr(); _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); jzpos = _fs->GetCurrentPos(); } + Expect(_SC(';')); + _fs->SnoozeOpt(); + SQInteger expstart = _fs->GetCurrentPos() + 1; + if(_token != _SC(')')) { + CommaExpr(); + _fs->PopTarget(); + } + Expect(_SC(')')); + _fs->SnoozeOpt(); + SQInteger expend = _fs->GetCurrentPos(); + SQInteger expsize = (expend - expstart) + 1; + SQInstructionVec exp; + if(expsize > 0) { + for(SQInteger i = 0; i < expsize; i++) + exp.push_back(_fs->GetInstruction(expstart + i)); + _fs->PopInstructions(expsize); + } + BEGIN_BREAKBLE_BLOCK() + Statement(); + SQInteger continuetrg = _fs->GetCurrentPos(); + if(expsize > 0) { + for(SQInteger i = 0; i < expsize; i++) + _fs->AddInstruction(exp[i]); + } + _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1, 0); + if(jzpos> 0) _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos); + END_SCOPE(); + + END_BREAKBLE_BLOCK(continuetrg); + } + void ForEachStatement() + { + SQObject idxname, valname; + Lex(); Expect(_SC('(')); valname = Expect(TK_IDENTIFIER); + if(_token == _SC(',')) { + idxname = valname; + Lex(); valname = Expect(TK_IDENTIFIER); + } + else{ + idxname = _fs->CreateString(_SC("@INDEX@")); + } + Expect(TK_IN); + + //save the stack size + BEGIN_SCOPE(); + //put the table in the stack(evaluate the table expression) + Expression(); Expect(_SC(')')); + SQInteger container = _fs->TopTarget(); + //push the index local var + SQInteger indexpos = _fs->PushLocalVariable(idxname); + _fs->AddInstruction(_OP_LOADNULLS, indexpos,1); + //push the value local var + SQInteger valuepos = _fs->PushLocalVariable(valname); + _fs->AddInstruction(_OP_LOADNULLS, valuepos,1); + //push reference index + SQInteger itrpos = _fs->PushLocalVariable(_fs->CreateString(_SC("@ITERATOR@"))); //use invalid id to make it inaccessible + _fs->AddInstruction(_OP_LOADNULLS, itrpos,1); + SQInteger jmppos = _fs->GetCurrentPos(); + _fs->AddInstruction(_OP_FOREACH, container, 0, indexpos); + SQInteger foreachpos = _fs->GetCurrentPos(); + _fs->AddInstruction(_OP_POSTFOREACH, container, 0, indexpos); + //generate the statement code + BEGIN_BREAKBLE_BLOCK() + Statement(); + _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1); + _fs->SetIntructionParam(foreachpos, 1, _fs->GetCurrentPos() - foreachpos); + _fs->SetIntructionParam(foreachpos + 1, 1, _fs->GetCurrentPos() - foreachpos); + END_BREAKBLE_BLOCK(foreachpos - 1); + //restore the local variable stack(remove index,val and ref idx) + _fs->PopTarget(); + END_SCOPE(); + } + void SwitchStatement() + { + Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); + Expect(_SC('{')); + SQInteger expr = _fs->TopTarget(); + bool bfirst = true; + SQInteger tonextcondjmp = -1; + SQInteger skipcondjmp = -1; + SQInteger __nbreaks__ = _fs->_unresolvedbreaks.size(); + _fs->_breaktargets.push_back(0); + while(_token == TK_CASE) { + if(!bfirst) { + _fs->AddInstruction(_OP_JMP, 0, 0); + skipcondjmp = _fs->GetCurrentPos(); + _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp); + } + //condition + Lex(); Expression(); Expect(_SC(':')); + SQInteger trg = _fs->PopTarget(); + SQInteger eqtarget = trg; + bool local = _fs->IsLocal(trg); + if(local) { + eqtarget = _fs->PushTarget(); //we need to allocate a extra reg + } + _fs->AddInstruction(_OP_EQ, eqtarget, trg, expr); + _fs->AddInstruction(_OP_JZ, eqtarget, 0); + if(local) { + _fs->PopTarget(); + } + + //end condition + if(skipcondjmp != -1) { + _fs->SetIntructionParam(skipcondjmp, 1, (_fs->GetCurrentPos() - skipcondjmp)); + } + tonextcondjmp = _fs->GetCurrentPos(); + BEGIN_SCOPE(); + Statements(); + END_SCOPE(); + bfirst = false; + } + if(tonextcondjmp != -1) + _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp); + if(_token == TK_DEFAULT) { + Lex(); Expect(_SC(':')); + BEGIN_SCOPE(); + Statements(); + END_SCOPE(); + } + Expect(_SC('}')); + _fs->PopTarget(); + __nbreaks__ = _fs->_unresolvedbreaks.size() - __nbreaks__; + if(__nbreaks__ > 0)ResolveBreaks(_fs, __nbreaks__); + _fs->_breaktargets.pop_back(); + } + void FunctionStatement() + { + SQObject id; + Lex(); id = Expect(TK_IDENTIFIER); + _fs->PushTarget(0); + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); + if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET); + + while(_token == TK_DOUBLE_COLON) { + Lex(); + id = Expect(TK_IDENTIFIER); + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); + if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET); + } + Expect(_SC('(')); + CreateFunction(id); + _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0); + EmitDerefOp(_OP_NEWSLOT); + _fs->PopTarget(); + } + void ClassStatement() + { + SQExpState es; + Lex(); + es = _es; + _es.donot_get = true; + PrefixedExpr(); + if(_es.etype == EXPR) { + Error(_SC("invalid class name")); + } + else if(_es.etype == OBJECT || _es.etype == BASE) { + ClassExp(); + EmitDerefOp(_OP_NEWSLOT); + _fs->PopTarget(); + } + else { + Error(_SC("cannot create a class in a local with the syntax(class )")); + } + _es = es; + } + SQObject ExpectScalar() + { + SQObject val; + val._type = OT_NULL; val._unVal.nInteger = 0; //shut up GCC 4.x + switch(_token) { + case TK_INTEGER: + val._type = OT_INTEGER; + val._unVal.nInteger = _lex._nvalue; + break; + case TK_FLOAT: + val._type = OT_FLOAT; + val._unVal.fFloat = _lex._fvalue; + break; + case TK_STRING_LITERAL: + val = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1); + break; + case TK_TRUE: + case TK_FALSE: + val._type = OT_BOOL; + val._unVal.nInteger = _token == TK_TRUE ? 1 : 0; + break; + case '-': + Lex(); + switch(_token) + { + case TK_INTEGER: + val._type = OT_INTEGER; + val._unVal.nInteger = -_lex._nvalue; + break; + case TK_FLOAT: + val._type = OT_FLOAT; + val._unVal.fFloat = -_lex._fvalue; + break; + default: + Error(_SC("scalar expected : integer,float")); + } + break; + default: + Error(_SC("scalar expected : integer,float or string")); + } + Lex(); + return val; + } + void EnumStatement() + { + Lex(); + SQObject id = Expect(TK_IDENTIFIER); + Expect(_SC('{')); + + SQObject table = _fs->CreateTable(); + SQInteger nval = 0; + while(_token != _SC('}')) { + SQObject key = Expect(TK_IDENTIFIER); + SQObject val; + if(_token == _SC('=')) { + Lex(); + val = ExpectScalar(); + } + else { + val._type = OT_INTEGER; + val._unVal.nInteger = nval++; + } + _table(table)->NewSlot(SQObjectPtr(key),SQObjectPtr(val)); + if(_token == ',') Lex(); + } + SQTable *enums = _table(_ss(_vm)->_consts); + SQObjectPtr strongid = id; + enums->NewSlot(SQObjectPtr(strongid),SQObjectPtr(table)); + strongid.Null(); + Lex(); + } + void TryCatchStatement() + { + SQObject exid; + Lex(); + _fs->AddInstruction(_OP_PUSHTRAP,0,0); + _fs->_traps++; + if(_fs->_breaktargets.size()) _fs->_breaktargets.top()++; + if(_fs->_continuetargets.size()) _fs->_continuetargets.top()++; + SQInteger trappos = _fs->GetCurrentPos(); + { + BEGIN_SCOPE(); + Statement(); + END_SCOPE(); + } + _fs->_traps--; + _fs->AddInstruction(_OP_POPTRAP, 1, 0); + if(_fs->_breaktargets.size()) _fs->_breaktargets.top()--; + if(_fs->_continuetargets.size()) _fs->_continuetargets.top()--; + _fs->AddInstruction(_OP_JMP, 0, 0); + SQInteger jmppos = _fs->GetCurrentPos(); + _fs->SetIntructionParam(trappos, 1, (_fs->GetCurrentPos() - trappos)); + Expect(TK_CATCH); Expect(_SC('(')); exid = Expect(TK_IDENTIFIER); Expect(_SC(')')); + { + BEGIN_SCOPE(); + SQInteger ex_target = _fs->PushLocalVariable(exid); + _fs->SetIntructionParam(trappos, 0, ex_target); + Statement(); + _fs->SetIntructionParams(jmppos, 0, (_fs->GetCurrentPos() - jmppos), 0); + END_SCOPE(); + } + } + void FunctionExp(SQInteger ftype,bool lambda = false) + { + Lex(); Expect(_SC('(')); + SQObjectPtr dummy; + CreateFunction(dummy,lambda); + _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, ftype == TK_FUNCTION?0:1); + } + void ClassExp() + { + SQInteger base = -1; + SQInteger attrs = -1; + if(_token == TK_EXTENDS) { + Lex(); Expression(); + base = _fs->TopTarget(); + } + if(_token == TK_ATTR_OPEN) { + Lex(); + _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE); + ParseTableOrClass(_SC(','),TK_ATTR_CLOSE); + attrs = _fs->TopTarget(); + } + Expect(_SC('{')); + if(attrs != -1) _fs->PopTarget(); + if(base != -1) _fs->PopTarget(); + _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(), base, attrs,NOT_CLASS); + ParseTableOrClass(_SC(';'),_SC('}')); + } + void DeleteExpr() + { + SQExpState es; + Lex(); + es = _es; + _es.donot_get = true; + PrefixedExpr(); + if(_es.etype==EXPR) Error(_SC("can't delete an expression")); + if(_es.etype==OBJECT || _es.etype==BASE) { + Emit2ArgsOP(_OP_DELETE); + } + else { + Error(_SC("cannot delete an (outer) local")); + } + _es = es; + } + void PrefixIncDec(SQInteger token) + { + SQExpState es; + SQInteger diff = (token==TK_MINUSMINUS) ? -1 : 1; + Lex(); + es = _es; + _es.donot_get = true; + PrefixedExpr(); + if(_es.etype==EXPR) { + Error(_SC("can't '++' or '--' an expression")); + } + else if(_es.etype==OBJECT || _es.etype==BASE) { + Emit2ArgsOP(_OP_INC, diff); + } + else if(_es.etype==LOCAL) { + SQInteger src = _fs->TopTarget(); + _fs->AddInstruction(_OP_INCL, src, src, 0, diff); + + } + else if(_es.etype==OUTER) { + SQInteger tmp = _fs->PushTarget(); + _fs->AddInstruction(_OP_GETOUTER, tmp, _es.epos); + _fs->AddInstruction(_OP_INCL, tmp, tmp, 0, diff); + _fs->AddInstruction(_OP_SETOUTER, tmp, _es.epos, tmp); + } + _es = es; + } + void CreateFunction(SQObject &name,bool lambda = false) + { + SQFuncState *funcstate = _fs->PushChildState(_ss(_vm)); + funcstate->_name = name; + SQObject paramname; + funcstate->AddParameter(_fs->CreateString(_SC("this"))); + funcstate->_sourcename = _sourcename; + SQInteger defparams = 0; + while(_token!=_SC(')')) { + if(_token == TK_VARPARAMS) { + if(defparams > 0) Error(_SC("function with default parameters cannot have variable number of parameters")); + funcstate->AddParameter(_fs->CreateString(_SC("vargv"))); + funcstate->_varparams = true; + Lex(); + if(_token != _SC(')')) Error(_SC("expected ')'")); + break; + } + else { + paramname = Expect(TK_IDENTIFIER); + funcstate->AddParameter(paramname); + if(_token == _SC('=')) { + Lex(); + Expression(); + funcstate->AddDefaultParam(_fs->TopTarget()); + defparams++; + } + else { + if(defparams > 0) Error(_SC("expected '='")); + } + if(_token == _SC(',')) Lex(); + else if(_token != _SC(')')) Error(_SC("expected ')' or ','")); + } + } + Expect(_SC(')')); + for(SQInteger n = 0; n < defparams; n++) { + _fs->PopTarget(); + } + + SQFuncState *currchunk = _fs; + _fs = funcstate; + if(lambda) { + Expression(); + _fs->AddInstruction(_OP_RETURN, 1, _fs->PopTarget());} + else { + Statement(false); + } + funcstate->AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true); + funcstate->AddInstruction(_OP_RETURN, -1); + funcstate->SetStackSize(0); + + SQFunctionProto *func = funcstate->BuildProto(); +#ifdef _DEBUG_DUMP + funcstate->Dump(func); +#endif + _fs = currchunk; + _fs->_functions.push_back(func); + _fs->PopChildState(); + } + void ResolveBreaks(SQFuncState *funcstate, SQInteger ntoresolve) + { + while(ntoresolve > 0) { + SQInteger pos = funcstate->_unresolvedbreaks.back(); + funcstate->_unresolvedbreaks.pop_back(); + //set the jmp instruction + funcstate->SetIntructionParams(pos, 0, funcstate->GetCurrentPos() - pos, 0); + ntoresolve--; + } + } + void ResolveContinues(SQFuncState *funcstate, SQInteger ntoresolve, SQInteger targetpos) + { + while(ntoresolve > 0) { + SQInteger pos = funcstate->_unresolvedcontinues.back(); + funcstate->_unresolvedcontinues.pop_back(); + //set the jmp instruction + funcstate->SetIntructionParams(pos, 0, targetpos - pos, 0); + ntoresolve--; + } + } +private: + SQInteger _token; + SQFuncState *_fs; + SQObjectPtr _sourcename; + SQLexer _lex; + bool _lineinfo; + bool _raiseerror; + SQInteger _debugline; + SQInteger _debugop; + SQExpState _es; + SQScope _scope; + SQChar _compilererror[MAX_COMPILER_ERROR_LEN]; + jmp_buf _errorjmp; + SQVM *_vm; +}; + +bool Compile(SQVM *vm,SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo) +{ + SQCompiler p(vm, rg, up, sourcename, raiseerror, lineinfo); + return p.Compile(out); +} + +#endif diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqcompiler.h b/src/modules/app_sqlang/squirrel/squirrel/sqcompiler.h new file mode 100644 index 00000000000..65e283068ea --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqcompiler.h @@ -0,0 +1,78 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQCOMPILER_H_ +#define _SQCOMPILER_H_ + +struct SQVM; + +#define TK_IDENTIFIER 258 +#define TK_STRING_LITERAL 259 +#define TK_INTEGER 260 +#define TK_FLOAT 261 +#define TK_BASE 262 +#define TK_DELETE 263 +#define TK_EQ 264 +#define TK_NE 265 +#define TK_LE 266 +#define TK_GE 267 +#define TK_SWITCH 268 +#define TK_ARROW 269 +#define TK_AND 270 +#define TK_OR 271 +#define TK_IF 272 +#define TK_ELSE 273 +#define TK_WHILE 274 +#define TK_BREAK 275 +#define TK_FOR 276 +#define TK_DO 277 +#define TK_NULL 278 +#define TK_FOREACH 279 +#define TK_IN 280 +#define TK_NEWSLOT 281 +#define TK_MODULO 282 +#define TK_LOCAL 283 +#define TK_CLONE 284 +#define TK_FUNCTION 285 +#define TK_RETURN 286 +#define TK_TYPEOF 287 +#define TK_UMINUS 288 +#define TK_PLUSEQ 289 +#define TK_MINUSEQ 290 +#define TK_CONTINUE 291 +#define TK_YIELD 292 +#define TK_TRY 293 +#define TK_CATCH 294 +#define TK_THROW 295 +#define TK_SHIFTL 296 +#define TK_SHIFTR 297 +#define TK_RESUME 298 +#define TK_DOUBLE_COLON 299 +#define TK_CASE 300 +#define TK_DEFAULT 301 +#define TK_THIS 302 +#define TK_PLUSPLUS 303 +#define TK_MINUSMINUS 304 +#define TK_3WAYSCMP 305 +#define TK_USHIFTR 306 +#define TK_CLASS 307 +#define TK_EXTENDS 308 +#define TK_CONSTRUCTOR 310 +#define TK_INSTANCEOF 311 +#define TK_VARPARAMS 312 +#define TK___LINE__ 313 +#define TK___FILE__ 314 +#define TK_TRUE 315 +#define TK_FALSE 316 +#define TK_MULEQ 317 +#define TK_DIVEQ 318 +#define TK_MODEQ 319 +#define TK_ATTR_OPEN 320 +#define TK_ATTR_CLOSE 321 +#define TK_STATIC 322 +#define TK_ENUM 323 +#define TK_CONST 324 + + + +typedef void(*CompilerErrorFunc)(void *ud, const SQChar *s); +bool Compile(SQVM *vm, SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo); +#endif //_SQCOMPILER_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqdebug.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqdebug.cpp new file mode 100644 index 00000000000..00f2b1ff234 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqdebug.cpp @@ -0,0 +1,118 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include +#include "sqvm.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "sqstring.h" + +SQRESULT sq_getfunctioninfo(HSQUIRRELVM 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 = type(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown"); + fi->source = 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(HSQUIRRELVM 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 (type(ci._closure)) { + case OT_CLOSURE:{ + SQFunctionProto *func = _closure(ci._closure)->_function; + if (type(func->_name) == OT_STRING) + si->funcname = _stringval(func->_name); + if (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(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); +} + +void SQVM::Raise_Error(const SQObjectPtr &desc) +{ + _lasterror = desc; +} + +SQString *SQVM::PrintObjVal(const SQObjectPtr &o) +{ + switch(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)); +} + +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)); +} + + +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 = 0x00000001 << 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)); +} diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqfuncproto.h b/src/modules/app_sqlang/squirrel/squirrel/sqfuncproto.h new file mode 100644 index 00000000000..c1016ae2773 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqfuncproto.h @@ -0,0 +1,154 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQFUNCTION_H_ +#define _SQFUNCTION_H_ + +#include "sqopcodes.h" + +enum SQOuterType { + 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; +}; + +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; +}; + +struct SQLineInfo { SQInteger _line;SQInteger _op; }; + +typedef sqvector SQOuterVarVec; +typedef sqvector SQLocalVarInfoVec; +typedef sqvector 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))) + + +struct SQFunctionProto : public CHAINABLE_OBJ +{ +private: + 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; + + _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); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize(){ _NULL_SQOBJECT_VECTOR(_literals,_nliterals); } + SQObjectType GetType() {return OT_FUNCPROTO;} +#endif + SQObjectPtr _sourcename; + SQObjectPtr _name; + SQInteger _stacksize; + bool _bgenerator; + SQInteger _varparams; + + SQInteger _nlocalvarinfos; + SQLocalVarInfo *_localvarinfos; + + SQInteger _nlineinfos; + SQLineInfo *_lineinfos; + + SQInteger _nliterals; + SQObjectPtr *_literals; + + SQInteger _nparameters; + SQObjectPtr *_parameters; + + SQInteger _nfunctions; + SQObjectPtr *_functions; + + SQInteger _noutervalues; + SQOuterVar *_outervalues; + + SQInteger _ndefaultparams; + SQInteger *_defaultparams; + + SQInteger _ninstructions; + SQInstruction _instructions[1]; +}; + +#endif //_SQFUNCTION_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.cpp new file mode 100644 index 00000000000..cc127b3f9af --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.cpp @@ -0,0 +1,653 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#ifndef NO_COMPILER +#include "sqcompiler.h" +#include "sqstring.h" +#include "sqfuncproto.h" +#include "sqtable.h" +#include "sqopcodes.h" +#include "sqfuncstate.h" + +#ifdef _DEBUG_DUMP +SQInstructionDesc g_InstrDesc[]={ + {_SC("_OP_LINE")}, + {_SC("_OP_LOAD")}, + {_SC("_OP_LOADINT")}, + {_SC("_OP_LOADFLOAT")}, + {_SC("_OP_DLOAD")}, + {_SC("_OP_TAILCALL")}, + {_SC("_OP_CALL")}, + {_SC("_OP_PREPCALL")}, + {_SC("_OP_PREPCALLK")}, + {_SC("_OP_GETK")}, + {_SC("_OP_MOVE")}, + {_SC("_OP_NEWSLOT")}, + {_SC("_OP_DELETE")}, + {_SC("_OP_SET")}, + {_SC("_OP_GET")}, + {_SC("_OP_EQ")}, + {_SC("_OP_NE")}, + {_SC("_OP_ADD")}, + {_SC("_OP_SUB")}, + {_SC("_OP_MUL")}, + {_SC("_OP_DIV")}, + {_SC("_OP_MOD")}, + {_SC("_OP_BITW")}, + {_SC("_OP_RETURN")}, + {_SC("_OP_LOADNULLS")}, + {_SC("_OP_LOADROOT")}, + {_SC("_OP_LOADBOOL")}, + {_SC("_OP_DMOVE")}, + {_SC("_OP_JMP")}, + {_SC("_OP_JCMP")}, + {_SC("_OP_JZ")}, + {_SC("_OP_SETOUTER")}, + {_SC("_OP_GETOUTER")}, + {_SC("_OP_NEWOBJ")}, + {_SC("_OP_APPENDARRAY")}, + {_SC("_OP_COMPARITH")}, + {_SC("_OP_INC")}, + {_SC("_OP_INCL")}, + {_SC("_OP_PINC")}, + {_SC("_OP_PINCL")}, + {_SC("_OP_CMP")}, + {_SC("_OP_EXISTS")}, + {_SC("_OP_INSTANCEOF")}, + {_SC("_OP_AND")}, + {_SC("_OP_OR")}, + {_SC("_OP_NEG")}, + {_SC("_OP_NOT")}, + {_SC("_OP_BWNOT")}, + {_SC("_OP_CLOSURE")}, + {_SC("_OP_YIELD")}, + {_SC("_OP_RESUME")}, + {_SC("_OP_FOREACH")}, + {_SC("_OP_POSTFOREACH")}, + {_SC("_OP_CLONE")}, + {_SC("_OP_TYPEOF")}, + {_SC("_OP_PUSHTRAP")}, + {_SC("_OP_POPTRAP")}, + {_SC("_OP_THROW")}, + {_SC("_OP_NEWSLOTA")}, + {_SC("_OP_GETBASE")}, + {_SC("_OP_CLOSE")}, +}; +#endif +void DumpLiteral(SQObjectPtr &o) +{ + switch(type(o)){ + case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break; + case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break; + case OT_INTEGER: scprintf(_SC("{") _PRINT_INT_FMT _SC("}"),_integer(o));break; + case OT_BOOL: scprintf(_SC("%s"),_integer(o)?_SC("true"):_SC("false"));break; + default: scprintf(_SC("(%s %p)"),GetTypeName(o),(void*)_rawval(o));break; break; //shut up compiler + } +} + +SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed) +{ + _nliterals = 0; + _literals = SQTable::Create(ss,0); + _strings = SQTable::Create(ss,0); + _sharedstate = ss; + _lastline = 0; + _optimization = true; + _parent = parent; + _stacksize = 0; + _traps = 0; + _returnexp = 0; + _varparams = false; + _errfunc = efunc; + _errtarget = ed; + _bgenerator = false; + _outers = 0; + _ss = ss; + +} + +void SQFuncState::Error(const SQChar *err) +{ + _errfunc(_errtarget,err); +} + +#ifdef _DEBUG_DUMP +void SQFuncState::Dump(SQFunctionProto *func) +{ + SQUnsignedInteger n=0,i; + SQInteger si; + scprintf(_SC("SQInstruction sizeof %d\n"),sizeof(SQInstruction)); + scprintf(_SC("SQObject sizeof %d\n"),sizeof(SQObject)); + scprintf(_SC("--------------------------------------------------------------------\n")); + scprintf(_SC("*****FUNCTION [%s]\n"),type(func->_name)==OT_STRING?_stringval(func->_name):_SC("unknown")); + scprintf(_SC("-----LITERALS\n")); + SQObjectPtr refidx,key,val; + SQInteger idx; + SQObjectPtrVec templiterals; + templiterals.resize(_nliterals); + while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) { + refidx=idx; + templiterals[_integer(val)]=key; + } + for(i=0;i>\n")); + n=0; + for(i=0;i<_parameters.size();i++){ + scprintf(_SC("[%d] "),n); + DumpLiteral(_parameters[i]); + scprintf(_SC("\n")); + n++; + } + scprintf(_SC("-----LOCALS\n")); + for(si=0;si_nlocalvarinfos;si++){ + SQLocalVarInfo lvi=func->_localvarinfos[si]; + scprintf(_SC("[%d] %s \t%d %d\n"),lvi._pos,_stringval(lvi._name),lvi._start_op,lvi._end_op); + n++; + } + scprintf(_SC("-----LINE INFO\n")); + for(i=0;i<_lineinfos.size();i++){ + SQLineInfo li=_lineinfos[i]; + scprintf(_SC("op [%d] line [%d] \n"),li._op,li._line); + n++; + } + scprintf(_SC("-----dump\n")); + n=0; + for(i=0;i<_instructions.size();i++){ + SQInstruction &inst=_instructions[i]; + if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){ + + SQInteger lidx = inst._arg1; + scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0); + if(lidx >= 0xFFFFFFFF) + scprintf(_SC("null")); + else { + SQInteger refidx; + SQObjectPtr val,key,refo; + while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { + refo = refidx; + } + DumpLiteral(key); + } + if(inst.op != _OP_DLOAD) { + scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3); + } + else { + scprintf(_SC(" %d "),inst._arg2); + lidx = inst._arg3; + if(lidx >= 0xFFFFFFFF) + scprintf(_SC("null")); + else { + SQInteger refidx; + SQObjectPtr val,key,refo; + while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { + refo = refidx; + } + DumpLiteral(key); + scprintf(_SC("\n")); + } + } + } + else if(inst.op==_OP_LOADFLOAT) { + scprintf(_SC("[%03d] %15s %d %f %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,*((SQFloat*)&inst._arg1),inst._arg2,inst._arg3); + } + /* else if(inst.op==_OP_ARITH){ + scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); + }*/ + else { + scprintf(_SC("[%03d] %15s %d %d %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); + } + n++; + } + scprintf(_SC("-----\n")); + scprintf(_SC("stack size[%d]\n"),func->_stacksize); + scprintf(_SC("--------------------------------------------------------------------\n\n")); +} +#endif + +SQInteger SQFuncState::GetNumericConstant(const SQInteger cons) +{ + return GetConstant(SQObjectPtr(cons)); +} + +SQInteger SQFuncState::GetNumericConstant(const SQFloat cons) +{ + return GetConstant(SQObjectPtr(cons)); +} + +SQInteger SQFuncState::GetConstant(const SQObject &cons) +{ + SQObjectPtr val; + if(!_table(_literals)->Get(cons,val)) + { + val = _nliterals; + _table(_literals)->NewSlot(cons,val); + _nliterals++; + if(_nliterals > MAX_LITERALS) { + val.Null(); + Error(_SC("internal compiler error: too many literals")); + } + } + return _integer(val); +} + +void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3) +{ + _instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&arg0); + _instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&arg1); + _instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&arg2); + _instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&arg3); +} + +void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val) +{ + switch(arg){ + case 0:_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&val);break; + case 1:case 4:_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&val);break; + case 2:_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&val);break; + case 3:_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&val);break; + }; +} + +SQInteger SQFuncState::AllocStackPos() +{ + SQInteger npos=_vlocals.size(); + _vlocals.push_back(SQLocalVarInfo()); + if(_vlocals.size()>((SQUnsignedInteger)_stacksize)) { + if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals")); + _stacksize=_vlocals.size(); + } + return npos; +} + +SQInteger SQFuncState::PushTarget(SQInteger n) +{ + if(n!=-1){ + _targetstack.push_back(n); + return n; + } + n=AllocStackPos(); + _targetstack.push_back(n); + return n; +} + +SQInteger SQFuncState::GetUpTarget(SQInteger n){ + return _targetstack[((_targetstack.size()-1)-n)]; +} + +SQInteger SQFuncState::TopTarget(){ + return _targetstack.back(); +} +SQInteger SQFuncState::PopTarget() +{ + SQUnsignedInteger npos=_targetstack.back(); + assert(npos < _vlocals.size()); + SQLocalVarInfo &t = _vlocals[npos]; + if(type(t._name)==OT_NULL){ + _vlocals.pop_back(); + } + _targetstack.pop_back(); + return npos; +} + +SQInteger SQFuncState::GetStackSize() +{ + return _vlocals.size(); +} + +SQInteger SQFuncState::CountOuters(SQInteger stacksize) +{ + SQInteger outers = 0; + SQInteger k = _vlocals.size() - 1; + while(k >= stacksize) { + SQLocalVarInfo &lvi = _vlocals[k]; + k--; + if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer + outers++; + } + } + return outers; +} + +void SQFuncState::SetStackSize(SQInteger n) +{ + SQInteger size=_vlocals.size(); + while(size>n){ + size--; + SQLocalVarInfo lvi = _vlocals.back(); + if(type(lvi._name)!=OT_NULL){ + if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer + _outers--; + } + lvi._end_op = GetCurrentPos(); + _localvarinfos.push_back(lvi); + } + _vlocals.pop_back(); + } +} + +bool SQFuncState::IsConstant(const SQObject &name,SQObject &e) +{ + SQObjectPtr val; + if(_table(_sharedstate->_consts)->Get(name,val)) { + e = val; + return true; + } + return false; +} + +bool SQFuncState::IsLocal(SQUnsignedInteger stkpos) +{ + if(stkpos>=_vlocals.size())return false; + else if(type(_vlocals[stkpos]._name)!=OT_NULL)return true; + return false; +} + +SQInteger SQFuncState::PushLocalVariable(const SQObject &name) +{ + SQInteger pos=_vlocals.size(); + SQLocalVarInfo lvi; + lvi._name=name; + lvi._start_op=GetCurrentPos()+1; + lvi._pos=_vlocals.size(); + _vlocals.push_back(lvi); + if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size(); + return pos; +} + + + +SQInteger SQFuncState::GetLocalVariable(const SQObject &name) +{ + SQInteger locals=_vlocals.size(); + while(locals>=1){ + SQLocalVarInfo &lvi = _vlocals[locals-1]; + if(type(lvi._name)==OT_STRING && _string(lvi._name)==_string(name)){ + return locals-1; + } + locals--; + } + return -1; +} + +void SQFuncState::MarkLocalAsOuter(SQInteger pos) +{ + SQLocalVarInfo &lvi = _vlocals[pos]; + lvi._end_op = UINT_MINUS_ONE; + _outers++; +} + +SQInteger SQFuncState::GetOuterVariable(const SQObject &name) +{ + SQInteger outers = _outervalues.size(); + for(SQInteger i = 0; iGetLocalVariable(name); + if(pos == -1) { + pos = _parent->GetOuterVariable(name); + if(pos != -1) { + _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otOUTER)); //local + return _outervalues.size() - 1; + } + } + else { + _parent->MarkLocalAsOuter(pos); + _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); //local + return _outervalues.size() - 1; + + + } + } + return -1; +} + +void SQFuncState::AddParameter(const SQObject &name) +{ + PushLocalVariable(name); + _parameters.push_back(name); +} + +void SQFuncState::AddLineInfos(SQInteger line,bool lineop,bool force) +{ + if(_lastline!=line || force){ + SQLineInfo li; + li._line=line;li._op=(GetCurrentPos()+1); + if(lineop)AddInstruction(_OP_LINE,0,line); + if(_lastline!=line) { + _lineinfos.push_back(li); + } + _lastline=line; + } +} + +void SQFuncState::DiscardTarget() +{ + SQInteger discardedtarget = PopTarget(); + SQInteger size = _instructions.size(); + if(size > 0 && _optimization){ + SQInstruction &pi = _instructions[size-1];//previous instruction + switch(pi.op) { + case _OP_SET:case _OP_NEWSLOT:case _OP_SETOUTER:case _OP_CALL: + if(pi._arg0 == discardedtarget) { + pi._arg0 = 0xFF; + } + } + } +} + +void SQFuncState::AddInstruction(SQInstruction &i) +{ + SQInteger size = _instructions.size(); + if(size > 0 && _optimization){ //simple optimizer + SQInstruction &pi = _instructions[size-1];//previous instruction + switch(i.op) { + case _OP_JZ: + if( pi.op == _OP_CMP && pi._arg1 < 0xFF) { + pi.op = _OP_JCMP; + pi._arg0 = (unsigned char)pi._arg1; + pi._arg1 = i._arg1; + return; + } + break; + case _OP_SET: + case _OP_NEWSLOT: + if(i._arg0 == i._arg3) { + i._arg0 = 0xFF; + } + break; + case _OP_SETOUTER: + if(i._arg0 == i._arg2) { + i._arg0 = 0xFF; + } + break; + case _OP_RETURN: + if( _parent && i._arg0 != MAX_FUNC_STACKSIZE && pi.op == _OP_CALL && _returnexp < size-1) { + pi.op = _OP_TAILCALL; + } else if(pi.op == _OP_CLOSE){ + pi = i; + return; + } + break; + case _OP_GET: + if( pi.op == _OP_LOAD && pi._arg0 == i._arg2 && (!IsLocal(pi._arg0))){ + pi._arg1 = pi._arg1; + pi._arg2 = (unsigned char)i._arg1; + pi.op = _OP_GETK; + pi._arg0 = i._arg0; + + return; + } + break; + case _OP_PREPCALL: + if( pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){ + pi.op = _OP_PREPCALLK; + pi._arg0 = i._arg0; + pi._arg1 = pi._arg1; + pi._arg2 = i._arg2; + pi._arg3 = i._arg3; + return; + } + break; + case _OP_APPENDARRAY: { + SQInteger aat = -1; + switch(pi.op) { + case _OP_LOAD: aat = AAT_LITERAL; break; + case _OP_LOADINT: aat = AAT_INT; break; + case _OP_LOADBOOL: aat = AAT_BOOL; break; + case _OP_LOADFLOAT: aat = AAT_FLOAT; break; + default: break; + } + if(aat != -1 && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){ + pi.op = _OP_APPENDARRAY; + pi._arg0 = i._arg0; + pi._arg1 = pi._arg1; + pi._arg2 = (unsigned char)aat; + pi._arg3 = MAX_FUNC_STACKSIZE; + return; + } + } + break; + case _OP_MOVE: + switch(pi.op) { + case _OP_GET: case _OP_ADD: case _OP_SUB: case _OP_MUL: case _OP_DIV: case _OP_MOD: case _OP_BITW: + case _OP_LOADINT: case _OP_LOADFLOAT: case _OP_LOADBOOL: case _OP_LOAD: + + if(pi._arg0 == i._arg1) + { + pi._arg0 = i._arg0; + _optimization = false; + //_result_elimination = false; + return; + } + } + + if(pi.op == _OP_MOVE) + { + pi.op = _OP_DMOVE; + pi._arg2 = i._arg0; + pi._arg3 = (unsigned char)i._arg1; + return; + } + break; + case _OP_LOAD: + if(pi.op == _OP_LOAD && i._arg1 < 256) { + pi.op = _OP_DLOAD; + pi._arg2 = i._arg0; + pi._arg3 = (unsigned char)i._arg1; + return; + } + break; + case _OP_EQ:case _OP_NE: + if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) )) + { + pi.op = i.op; + pi._arg0 = i._arg0; + pi._arg1 = pi._arg1; + pi._arg2 = i._arg2; + pi._arg3 = MAX_FUNC_STACKSIZE; + return; + } + break; + case _OP_LOADNULLS: + if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) { + + pi._arg1 = pi._arg1 + 1; + pi.op = _OP_LOADNULLS; + return; + } + break; + case _OP_LINE: + if(pi.op == _OP_LINE) { + _instructions.pop_back(); + _lineinfos.pop_back(); + } + break; + } + } + _optimization = true; + _instructions.push_back(i); +} + +SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len) +{ + SQObjectPtr ns(SQString::Create(_sharedstate,s,len)); + _table(_strings)->NewSlot(ns,(SQInteger)1); + return ns; +} + +SQObject SQFuncState::CreateTable() +{ + SQObjectPtr nt(SQTable::Create(_sharedstate,0)); + _table(_strings)->NewSlot(nt,(SQInteger)1); + return nt; +} + +SQFunctionProto *SQFuncState::BuildProto() +{ + + SQFunctionProto *f=SQFunctionProto::Create(_ss,_instructions.size(), + _nliterals,_parameters.size(),_functions.size(),_outervalues.size(), + _lineinfos.size(),_localvarinfos.size(),_defaultparams.size()); + + SQObjectPtr refidx,key,val; + SQInteger idx; + + f->_stacksize = _stacksize; + f->_sourcename = _sourcename; + f->_bgenerator = _bgenerator; + f->_name = _name; + + while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) { + f->_literals[_integer(val)]=key; + refidx=idx; + } + + for(SQUnsignedInteger nf = 0; nf < _functions.size(); nf++) f->_functions[nf] = _functions[nf]; + for(SQUnsignedInteger np = 0; np < _parameters.size(); np++) f->_parameters[np] = _parameters[np]; + for(SQUnsignedInteger no = 0; no < _outervalues.size(); no++) f->_outervalues[no] = _outervalues[no]; + for(SQUnsignedInteger nl = 0; nl < _localvarinfos.size(); nl++) f->_localvarinfos[nl] = _localvarinfos[nl]; + for(SQUnsignedInteger ni = 0; ni < _lineinfos.size(); ni++) f->_lineinfos[ni] = _lineinfos[ni]; + for(SQUnsignedInteger nd = 0; nd < _defaultparams.size(); nd++) f->_defaultparams[nd] = _defaultparams[nd]; + + memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(SQInstruction)); + + f->_varparams = _varparams; + + return f; +} + +SQFuncState *SQFuncState::PushChildState(SQSharedState *ss) +{ + SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState)); + new (child) SQFuncState(ss,this,_errfunc,_errtarget); + _childstates.push_back(child); + return child; +} + +void SQFuncState::PopChildState() +{ + SQFuncState *child = _childstates.back(); + sq_delete(child,SQFuncState); + _childstates.pop_back(); +} + +SQFuncState::~SQFuncState() +{ + while(_childstates.size() > 0) + { + PopChildState(); + } +} + +#endif diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.h b/src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.h new file mode 100644 index 00000000000..4bf2702e0c8 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.h @@ -0,0 +1,91 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQFUNCSTATE_H_ +#define _SQFUNCSTATE_H_ +/////////////////////////////////// +#include "squtils.h" + +struct SQFuncState +{ + SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed); + ~SQFuncState(); +#ifdef _DEBUG_DUMP + 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 _childstates; + SQInteger GetConstant(const SQObject &cons); +private: + CompilerErrorFunc _errfunc; + void *_errtarget; + SQSharedState *_ss; +}; + + +#endif //_SQFUNCSTATE_H_ + diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqlexer.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqlexer.cpp new file mode 100644 index 00000000000..bf538b8a102 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqlexer.cpp @@ -0,0 +1,561 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include +#include +#include "sqtable.h" +#include "sqstring.h" +#include "sqcompiler.h" +#include "sqlexer.h" + +#define CUR_CHAR (_currdata) +#define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;} +#define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB) +#define NEXT() {Next();_currentcolumn++;} +#define INIT_TEMP_STRING() { _longstr.resize(0);} +#define APPEND_CHAR(c) { _longstr.push_back(c);} +#define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));} +#define ADD_KEYWORD(key,id) _keywords->NewSlot( SQString::Create(ss, _SC(#key)) ,SQInteger(id)) + +SQLexer::SQLexer(){} +SQLexer::~SQLexer() +{ + _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__); + + _readf = rg; + _up = up; + _lasttokenline = _currentline = 1; + _currentcolumn = 0; + _prevtoken = -1; + _reached_eof = SQFalse; + Next(); +} + +void SQLexer::Error(const SQChar *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 = SQUIRREL_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; +} + +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 SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment")); + default: NEXT(); + } + } +} +void SQLexer::LexLineComment() +{ + do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB())); +} + +SQInteger SQLexer::Lex() +{ + _lasttokenline = _currentline; + while(CUR_CHAR != SQUIRREL_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 SQUIRREL_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; +} + +#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; + } +} +#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; +} +#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; +} + +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 SQUIRREL_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 = x == 'u' ? 4 : 8; + SQChar temp[8 + 1]; + ProcessStringHexEscape(temp, maxdigits); + SQChar *stemp; +#ifdef SQUNICODE +#if WCHAR_SIZE == 2 + AddUTF16(scstrtoul(temp, &stemp, 16)); +#else + ADD_CHAR((SQChar)scstrtoul(temp, &stemp, 16)); +#endif +#else + 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; +} + +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); } + } +} + +void LexInteger(const SQChar *s,SQUnsignedInteger *res) +{ + *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); } + } +} + +SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; } + + +#define MAX_HEX_DIGITS (sizeof(SQInteger)*2) +SQInteger SQLexer::ReadNumber() +{ +#define TINT 1 +#define TFLOAT 2 +#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")); + } + + 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; +} diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqlexer.h b/src/modules/app_sqlang/squirrel/squirrel/sqlexer.h new file mode 100644 index 00000000000..09055b321a7 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqlexer.h @@ -0,0 +1,55 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQLEXER_H_ +#define _SQLEXER_H_ + +#ifdef SQUNICODE +typedef SQChar LexChar; +#else +typedef unsigned char LexChar; +#endif + +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); +private: + 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); +#endif +#else + SQInteger AddUTF8(SQUnsignedInteger ch); +#endif + 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 _longstr; + CompilerErrorFunc _errfunc; + void *_errtarget; +}; + +#endif diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqmem.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqmem.cpp new file mode 100644 index 00000000000..d6f9e8f56fd --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqmem.cpp @@ -0,0 +1,11 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#ifndef SQ_EXCLUDE_DEFAULT_MEMFUNCTIONS +void *sq_vm_malloc(SQUnsignedInteger size){ return malloc(size); } + +void *sq_vm_realloc(void *p, SQUnsignedInteger SQ_UNUSED_ARG(oldsize), SQUnsignedInteger size){ return realloc(p, size); } + +void sq_vm_free(void *p, SQUnsignedInteger SQ_UNUSED_ARG(size)){ free(p); } +#endif diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqobject.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqobject.cpp new file mode 100644 index 00000000000..d5e84c9efcd --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqobject.cpp @@ -0,0 +1,677 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqstring.h" +#include "sqarray.h" +#include "sqtable.h" +#include "squserdata.h" +#include "sqfuncproto.h" +#include "sqclass.h" +#include "sqclosure.h" + + +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; + } +} + +const SQChar *GetTypeName(const SQObjectPtr &obj1) +{ + return IdType2Name(type(obj1)); +} + +SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len) +{ + SQString *str=ADD_STRING(ss,s,len); + return str; +} + +void SQString::Release() +{ + 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; +} + +SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx) +{ + switch(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 defined(SQUSEDOUBLE) && !defined(_SQ64) + _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; +} + +SQRefCounted::~SQRefCounted() +{ + 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); +} + +bool SQDelegable::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) { + 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; +} + +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; + + _stack.resize(size); + SQObject _this = v->_stack[v->_stackbase]; + _stack._vals[0] = ISREFCOUNTED(type(_this)) ? SQObjectPtr(_refcounted(_this)->GetWeakRef(type(_this))) : _this; + for(SQInteger n =1; n_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; +} + +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; + + + 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] = type(_this) == OT_WEAKREF ? _weakref(_this)->_obj : _this; + + for(SQInteger n = 1; n_stack[v->_stackbase+n] = _stack._vals[n]; + _stack._vals[n].Null(); + } + + _state=eRunning; + if (v->_debughook) + v->CallDebugHook(_SC('c')); + + return true; +} + +void SQArray::Extend(const SQArray *a){ + SQInteger xlen; + if((xlen=a->Size())) + for(SQInteger i=0;i_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=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; + } + } + + while(mid > 0 && _lineinfos[mid]._op >= op) mid--; + + line = _lineinfos[mid]._line; + + return line; +} + +SQClosure::~SQClosure() +{ + __ObjRelease(_root); + __ObjRelease(_env); + __ObjRelease(_base); + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); +} + +#define _CHECK_IO(exp) { if(!exp)return false; } +bool SafeWrite(HSQUIRRELVM 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; +} + +bool SafeRead(HSQUIRRELVM 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; +} + +bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUnsignedInteger32 tag) +{ + return SafeWrite(v,write,up,&tag,sizeof(tag)); +} + +bool CheckTag(HSQUIRRELVM 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; +} + +bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o) +{ + SQUnsignedInteger32 _type = (SQUnsignedInteger32)type(o); + _CHECK_IO(SafeWrite(v,write,up,&_type,sizeof(_type))); + switch(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(HSQUIRRELVM 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; +} + +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; +} + +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; +} + +SQFunctionProto::SQFunctionProto(SQSharedState *ss) +{ + _stacksize=0; + _bgenerator=false; + INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); +} + +SQFunctionProto::~SQFunctionProto() +{ + 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;iSave(v,up,write)); + } + _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize))); + _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator))); + _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams))); + return true; +} + +bool SQFunctionProto::Load(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)); + + _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(_opt_ss(v),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)); + + for(i = 0;i < nliterals; i++){ + _CHECK_IO(ReadObject(v, up, read, o)); + f->_literals[i] = o; + } + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + + for(i = 0; i < nparameters; i++){ + _CHECK_IO(ReadObject(v, up, read, o)); + f->_parameters[i] = o; + } + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + + for(i = 0; i < noutervalues; i++){ + 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)); + + _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)); + 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; +} + +#ifndef NO_GARBAGE_COLLECTOR + +#define START_MARK() if(!(_uiRef&MARK_FLAG)){ \ + _uiRef|=MARK_FLAG; + +#define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \ + AddToChain(chain, this); } + +void SQVM::Mark(SQCollectable **chain) +{ + START_MARK() + SQSharedState::MarkObject(_lasterror,chain); + SQSharedState::MarkObject(_errorhandler,chain); + SQSharedState::MarkObject(_debughook_closure,chain); + SQSharedState::MarkObject(_roottable, chain); + SQSharedState::MarkObject(temp_reg, chain); + for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain); + for(SQInteger k = 0; k < _callsstacksize; k++) SQSharedState::MarkObject(_callsstack[k]._closure, chain); + END_MARK() +} + +void SQArray::Mark(SQCollectable **chain) +{ + START_MARK() + SQInteger len = _values.size(); + for(SQInteger i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain); + END_MARK() +} +void SQTable::Mark(SQCollectable **chain) +{ + START_MARK() + if(_delegate) _delegate->Mark(chain); + SQInteger len = _numofnodes; + for(SQInteger i = 0; i < len; i++){ + SQSharedState::MarkObject(_nodes[i].key, chain); + SQSharedState::MarkObject(_nodes[i].val, chain); + } + END_MARK() +} + +void SQClass::Mark(SQCollectable **chain) +{ + START_MARK() + _members->Mark(chain); + if(_base) _base->Mark(chain); + SQSharedState::MarkObject(_attributes, chain); + for(SQUnsignedInteger i =0; i< _defaultvalues.size(); i++) { + SQSharedState::MarkObject(_defaultvalues[i].val, chain); + SQSharedState::MarkObject(_defaultvalues[i].attrs, chain); + } + for(SQUnsignedInteger j =0; j< _methods.size(); j++) { + SQSharedState::MarkObject(_methods[j].val, chain); + SQSharedState::MarkObject(_methods[j].attrs, chain); + } + for(SQUnsignedInteger k =0; k< MT_LAST; k++) { + SQSharedState::MarkObject(_metamethods[k], chain); + } + END_MARK() +} + +void SQInstance::Mark(SQCollectable **chain) +{ + START_MARK() + _class->Mark(chain); + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); + for(SQUnsignedInteger i =0; i< nvalues; i++) { + SQSharedState::MarkObject(_values[i], chain); + } + END_MARK() +} + +void SQGenerator::Mark(SQCollectable **chain) +{ + START_MARK() + for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain); + SQSharedState::MarkObject(_closure, chain); + END_MARK() +} + +void SQFunctionProto::Mark(SQCollectable **chain) +{ + START_MARK() + for(SQInteger i = 0; i < _nliterals; i++) SQSharedState::MarkObject(_literals[i], chain); + for(SQInteger k = 0; k < _nfunctions; k++) SQSharedState::MarkObject(_functions[k], chain); + END_MARK() +} + +void SQClosure::Mark(SQCollectable **chain) +{ + START_MARK() + if(_base) _base->Mark(chain); + SQFunctionProto *fp = _function; + fp->Mark(chain); + for(SQInteger i = 0; i < fp->_noutervalues; i++) SQSharedState::MarkObject(_outervalues[i], chain); + for(SQInteger k = 0; k < fp->_ndefaultparams; k++) SQSharedState::MarkObject(_defaultparams[k], chain); + END_MARK() +} + +void SQNativeClosure::Mark(SQCollectable **chain) +{ + START_MARK() + for(SQUnsignedInteger i = 0; i < _noutervalues; i++) SQSharedState::MarkObject(_outervalues[i], chain); + END_MARK() +} + +void SQOuter::Mark(SQCollectable **chain) +{ + START_MARK() + /* If the valptr points to a closed value, that value is alive */ + if(_valptr == &_value) { + SQSharedState::MarkObject(_value, chain); + } + END_MARK() +} + +void SQUserData::Mark(SQCollectable **chain){ + START_MARK() + if(_delegate) _delegate->Mark(chain); + END_MARK() +} + +void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; } + +#endif + diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqobject.h b/src/modules/app_sqlang/squirrel/squirrel/sqobject.h new file mode 100644 index 00000000000..34b78d0b45b --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqobject.h @@ -0,0 +1,354 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQOBJECT_H_ +#define _SQOBJECT_H_ + +#include "squtils.h" + +#ifdef _SQ64 +#define UINT_MINUS_ONE (0xFFFFFFFFFFFFFFFF) +#else +#define UINT_MINUS_ONE (0xFFFFFFFF) +#endif + +#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R')) +#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T')) +#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L')) + +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 +}; + +#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_TYPEOF _SC("_typeof") +#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") +#define MM_TOSTRING _SC("_tostring") +#define MM_NEWMEMBER _SC("_newmember") +#define MM_INHERITED _SC("_inherited") + + +#define _CONSTRUCT_VECTOR(type,size,ptr) { \ + 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(); \ + } \ +} + +#define _COPY_VECTOR(dest,src,size) { \ + 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(); \ + } \ +} + +#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; + +}; + +struct SQWeakRef : SQRefCounted +{ + void Release(); + SQObject _obj; +}; + +#define _realval(o) (type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj) + +struct SQObjectPtr; + +#define __AddRef(type,unval) if(ISREFCOUNTED(type)) \ + { \ + unval.pRefCounted->_uiRef++; \ + } + +#define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)==0)) \ + { \ + unval.pRefCounted->Release(); \ + } + +#define __ObjRelease(obj) { \ + if((obj)) { \ + (obj)->_uiRef--; \ + if((obj)->_uiRef == 0) \ + (obj)->Release(); \ + (obj) = NULL; \ + } \ +} + +#define __ObjAddRef(obj) { \ + (obj)->_uiRef++; \ +} + +#define type(obj) ((obj)._type) +#define is_delegable(t) (type(t)&SQOBJECT_DELEGABLE) +#define raw_type(obj) _RAW_TYPE((obj)._type) + +#define _integer(obj) ((obj)._unVal.nInteger) +#define _float(obj) ((obj)._unVal.fFloat) +#define _string(obj) ((obj)._unVal.pString) +#define _table(obj) ((obj)._unVal.pTable) +#define _array(obj) ((obj)._unVal.pArray) +#define _closure(obj) ((obj)._unVal.pClosure) +#define _generator(obj) ((obj)._unVal.pGenerator) +#define _nativeclosure(obj) ((obj)._unVal.pNativeClosure) +#define _userdata(obj) ((obj)._unVal.pUserData) +#define _userpointer(obj) ((obj)._unVal.pUserPointer) +#define _thread(obj) ((obj)._unVal.pThread) +#define _funcproto(obj) ((obj)._unVal.pFunctionProto) +#define _class(obj) ((obj)._unVal.pClass) +#define _instance(obj) ((obj)._unVal.pInstance) +#define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable) +#define _weakref(obj) ((obj)._unVal.pWeakRef) +#define _outer(obj) ((obj)._unVal.pOuter) +#define _refcounted(obj) ((obj)._unVal.pRefCounted) +#define _rawval(obj) ((obj)._unVal.raw) + +#define _stringval(obj) (obj)._unVal.pString->_val +#define _userdataval(obj) ((SQUserPointer)sq_aligning((obj)._unVal.pUserData + 1)) + +#define tofloat(num) ((type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num)) +#define tointeger(num) ((type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num)) +///////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////// +#if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64) +#define SQ_REFOBJECT_INIT() SQ_OBJECT_RAWINIT() +#else +#define SQ_REFOBJECT_INIT() +#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; \ + } + +#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; \ + } +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) + + _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() + { + __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 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; +} + +///////////////////////////////////////////////////////////////////////////////////// +#ifndef NO_GARBAGE_COLLECTOR +#define MARK_FLAG 0x80000000 +struct SQCollectable : public SQRefCounted { + SQCollectable *_next; + SQCollectable *_prev; + SQSharedState *_sharedstate; + virtual SQObjectType GetType()=0; + virtual void Release()=0; + virtual void Mark(SQCollectable **chain)=0; + void UnMark(); + virtual void Finalize()=0; + static void AddToChain(SQCollectable **chain,SQCollectable *c); + static void RemoveFromChain(SQCollectable **chain,SQCollectable *c); +}; + + +#define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj) +#define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);} +#define CHAINABLE_OBJ SQCollectable +#define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;} +#else + +#define ADD_TO_CHAIN(chain,obj) ((void)0) +#define REMOVE_FROM_CHAIN(chain,obj) ((void)0) +#define CHAINABLE_OBJ SQRefCounted +#define INIT_CHAIN() ((void)0) +#endif + +struct SQDelegable : public CHAINABLE_OBJ { + bool SetDelegate(SQTable *m); + virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res); + SQTable *_delegate; +}; + +SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx); +typedef sqvector SQObjectPtrVec; +typedef sqvector SQIntVec; +const SQChar *GetTypeName(const SQObjectPtr &obj1); +const SQChar *IdType2Name(SQObjectType type); + + + +#endif //_SQOBJECT_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqopcodes.h b/src/modules/app_sqlang/squirrel/squirrel/sqopcodes.h new file mode 100644 index 00000000000..1f5b16bd830 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqopcodes.h @@ -0,0 +1,132 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQOPCODES_H_ +#define _SQOPCODES_H_ + +#define MAX_FUNC_STACKSIZE 0xFF +#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 +}; + +enum CmpOP { + 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 +}; + +enum AppendArrayType { + 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 +}; + +struct SQInstructionDesc { + 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; + } + + + SQInt32 _arg1; + unsigned char op; + unsigned char _arg0; + unsigned char _arg2; + unsigned char _arg3; +}; + +#include "squtils.h" +typedef sqvector SQInstructionVec; + +#define NEW_SLOT_ATTRIBUTES_FLAG 0x01 +#define NEW_SLOT_STATIC_FLAG 0x02 + +#endif // _SQOPCODES_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqpcheader.h b/src/modules/app_sqlang/squirrel/squirrel/sqpcheader.h new file mode 100644 index 00000000000..941cb79437c --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqpcheader.h @@ -0,0 +1,20 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQPCHEADER_H_ +#define _SQPCHEADER_H_ + +#if defined(_MSC_VER) && defined(_DEBUG) +#include +#endif + +#include +#include +#include +#include +#include +#include +//squirrel stuff +#include +#include "sqobject.h" +#include "sqstate.h" + +#endif //_SQPCHEADER_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqstate.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqstate.cpp new file mode 100644 index 00000000000..cfb178b9a5d --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqstate.cpp @@ -0,0 +1,657 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqopcodes.h" +#include "sqvm.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "sqstring.h" +#include "sqtable.h" +#include "sqarray.h" +#include "squserdata.h" +#include "sqclass.h" + +//SQObjectPtr _null_; +//SQObjectPtr _true_(true); +//SQObjectPtr _false_(false); +//SQObjectPtr _one_((SQInteger)1); +//SQObjectPtr _minusone_((SQInteger)-1); + +SQSharedState::SQSharedState() +{ + _compilererrorhandler = NULL; + _printfunc = NULL; + _errorfunc = NULL; + _debuginfo = false; + _notifyallexceptions = false; + _foreignptr = NULL; + _releasehook = NULL; +} + +#define newsysstring(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)); \ + } + +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; + + } + 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; +} + +void SQSharedState::Init() +{ + _scratchpad=NULL; + _scratchpadsize=0; +#ifndef NO_GARBAGE_COLLECTOR + _gc_chain=NULL; +#endif + _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); + +} + +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(); +#ifndef NO_GARBAGE_COLLECTOR + SQCollectable *t = _gc_chain; + SQCollectable *nx = NULL; + if(t) { + t->_uiRef++; + while(t) { + t->Finalize(); + nx = t->_next; + if(nx) nx->_uiRef++; + if(--t->_uiRef == 0) + t->Release(); + t = nx; + } + } + assert(_gc_chain==NULL); //just to proove a theory + while(_gc_chain){ + _gc_chain->_uiRef++; + _gc_chain->Release(); + } +#endif + + 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(type(name) != OT_STRING) + return -1; + SQObjectPtr ret; + if(_table(_metamethodsmap)->Get(name,ret)) { + return _integer(ret); + } + return -1; +} + +#ifndef NO_GARBAGE_COLLECTOR + +void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain) +{ + switch(type(o)){ + case OT_TABLE:_table(o)->Mark(chain);break; + case OT_ARRAY:_array(o)->Mark(chain);break; + case OT_USERDATA:_userdata(o)->Mark(chain);break; + case OT_CLOSURE:_closure(o)->Mark(chain);break; + case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);break; + case OT_GENERATOR:_generator(o)->Mark(chain);break; + case OT_THREAD:_thread(o)->Mark(chain);break; + case OT_CLASS:_class(o)->Mark(chain);break; + case OT_INSTANCE:_instance(o)->Mark(chain);break; + case OT_OUTER:_outer(o)->Mark(chain);break; + case OT_FUNCPROTO:_funcproto(o)->Mark(chain);break; + default: break; //shutup compiler + } +} + +void SQSharedState::RunMark(SQVM SQ_UNUSED_ARG(*vm),SQCollectable **tchain) +{ + SQVM *vms = _thread(_root_vm); + + vms->Mark(tchain); + + _refs_table.Mark(tchain); + MarkObject(_registry,tchain); + MarkObject(_consts,tchain); + MarkObject(_metamethodsmap,tchain); + MarkObject(_table_default_delegate,tchain); + MarkObject(_array_default_delegate,tchain); + MarkObject(_string_default_delegate,tchain); + MarkObject(_number_default_delegate,tchain); + MarkObject(_generator_default_delegate,tchain); + MarkObject(_thread_default_delegate,tchain); + MarkObject(_closure_default_delegate,tchain); + MarkObject(_class_default_delegate,tchain); + MarkObject(_instance_default_delegate,tchain); + MarkObject(_weakref_default_delegate,tchain); + +} + +SQInteger SQSharedState::ResurrectUnreachable(SQVM *vm) +{ + SQInteger n=0; + SQCollectable *tchain=NULL; + + RunMark(vm,&tchain); + + SQCollectable *resurrected = _gc_chain; + SQCollectable *t = resurrected; + //SQCollectable *nx = NULL; + + _gc_chain = tchain; + + SQArray *ret = NULL; + if(resurrected) { + ret = SQArray::Create(this,0); + SQCollectable *rlast = NULL; + while(t) { + rlast = t; + SQObjectType type = t->GetType(); + if(type != OT_FUNCPROTO && type != OT_OUTER) { + SQObject sqo; + sqo._type = type; + sqo._unVal.pRefCounted = t; + ret->Append(sqo); + } + t = t->_next; + n++; + } + + assert(rlast->_next == NULL); + rlast->_next = _gc_chain; + if(_gc_chain) + { + _gc_chain->_prev = rlast; + } + _gc_chain = resurrected; + } + + t = _gc_chain; + while(t) { + t->UnMark(); + t = t->_next; + } + + if(ret) { + SQObjectPtr temp = ret; + vm->Push(temp); + } + else { + vm->PushNull(); + } + return n; +} + +SQInteger SQSharedState::CollectGarbage(SQVM *vm) +{ + SQInteger n = 0; + SQCollectable *tchain = NULL; + + RunMark(vm,&tchain); + + SQCollectable *t = _gc_chain; + SQCollectable *nx = NULL; + if(t) { + t->_uiRef++; + while(t) { + t->Finalize(); + nx = t->_next; + if(nx) nx->_uiRef++; + if(--t->_uiRef == 0) + t->Release(); + t = nx; + n++; + } + } + + t = tchain; + while(t) { + t->UnMark(); + t = t->_next; + } + _gc_chain = tchain; + + return n; +} +#endif + +#ifndef NO_GARBAGE_COLLECTOR +void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c) +{ + c->_prev = NULL; + c->_next = *chain; + if(*chain) (*chain)->_prev = c; + *chain = c; +} + +void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c) +{ + if(c->_prev) c->_prev->_next = c->_next; + else *chain = c->_next; + if(c->_next) + c->_next->_prev = c->_prev; + c->_next = NULL; + c->_prev = NULL; +} +#endif + +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; + + }else if(_scratchpadsize >= (size<<5)) { + newsize = _scratchpadsize >> 1; + _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); + _scratchpadsize = newsize; + } + } + return _scratchpad; +} + +RefTable::RefTable() +{ + AllocNodes(4); +} + +void RefTable::Finalize() +{ + 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))); +} + +#ifndef NO_GARBAGE_COLLECTOR +void RefTable::Mark(SQCollectable **chain) +{ + RefNode *nodes = (RefNode *)_nodes; + for(SQUnsignedInteger n = 0; n < _numofslots; n++) { + if(type(nodes->obj) != OT_NULL) { + SQSharedState::MarkObject(nodes->obj,chain); + } + nodes++; + } +} +#endif + +void RefTable::AddRef(SQObject &obj) +{ + 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; +} + + +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(); + //<>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(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; +} + +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) && type(ref->obj) == 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; +} +////////////////////////////////////////////////////////////////////////// +//SQStringTable +/* +* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.) +* http://www.lua.org/copyright.html#4 +* http://www.lua.org/source/4.0.1/src_lstring.c.html +*/ + +SQStringTable::SQStringTable(SQSharedState *ss) +{ + _sharedstate = ss; + AllocNodes(4); + _slotused = 0; +} + +SQStringTable::~SQStringTable() +{ + 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); +} + +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 + } + + 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_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); + + 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 +} diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqstate.h b/src/modules/app_sqlang/squirrel/squirrel/sqstate.h new file mode 100644 index 00000000000..cd1ac4965b1 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqstate.h @@ -0,0 +1,136 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTATE_H_ +#define _SQSTATE_H_ + +#include "squtils.h" +#include "sqobject.h" +struct SQString; +struct SQTable; +//max number of character for a printed number +#define NUMBER_MAX_CHAR 50 + +struct SQStringTable +{ + 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; +}; + +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); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); +#endif + 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; +}; + +#define ADD_STRING(ss,str,len) ss->_stringtable->Add(str,len) +#define REMOVE_STRING(ss,bstr) ss->_stringtable->Remove(bstr) + +struct SQObjectPtr; + +struct SQSharedState +{ + SQSharedState(); + ~SQSharedState(); + void Init(); +public: + SQChar* GetScratchPad(SQInteger size); + SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name); +#ifndef NO_GARBAGE_COLLECTOR + SQInteger CollectGarbage(SQVM *vm); + void RunMark(SQVM *vm,SQCollectable **tchain); + SQInteger ResurrectUnreachable(SQVM *vm); + static void MarkObject(SQObjectPtr &o,SQCollectable **chain); +#endif + SQObjectPtrVec *_metamethods; + SQObjectPtr _metamethodsmap; + SQObjectPtrVec *_systemstrings; + SQObjectPtrVec *_types; + SQStringTable *_stringtable; + RefTable _refs_table; + SQObjectPtr _registry; + SQObjectPtr _consts; + SQObjectPtr _constructoridx; +#ifndef NO_GARBAGE_COLLECTOR + SQCollectable *_gc_chain; +#endif + 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; +private: + 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 _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 _instance_ddel _table(_sharedstate->_instance_default_delegate) +#define _weakref_ddel _table(_sharedstate->_weakref_default_delegate) + +bool CompileTypemask(SQIntVec &res,const SQChar *typemask); + + +#endif //_SQSTATE_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqstring.h b/src/modules/app_sqlang/squirrel/squirrel/sqstring.h new file mode 100644 index 00000000000..1a8158a38c9 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqstring.h @@ -0,0 +1,31 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTRING_H_ +#define _SQSTRING_H_ + +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; +} + +struct SQString : public SQRefCounted +{ + 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]; +}; + + + +#endif //_SQSTRING_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqtable.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqtable.cpp new file mode 100644 index 00000000000..243ac694bf5 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqtable.cpp @@ -0,0 +1,221 @@ +/* +see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqtable.h" +#include "sqfuncproto.h" +#include "sqclosure.h" + +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); +} + +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); + } +} + +void SQTable::AllocNodes(SQInteger nSize) +{ + _HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize); + for(SQInteger i=0;i= 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; ikey) != OT_NULL) + NewSlot(old->key,old->val); + } + for(SQInteger k=0;k_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); + } +#endif + nt->SetDelegate(_delegate); + return nt; +} + +bool SQTable::Get(const SQObjectPtr &key,SQObjectPtr &val) +{ + if(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(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 + + if(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; + + for (;;) { /* correct `firstfree' */ + if (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(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; +} + +void SQTable::_ClearNodes() +{ + for(SQInteger i = 0;i < _numofnodes; i++) { _HashNode &n = _nodes[i]; n.key.Null(); n.val.Null(); } +} + +void SQTable::Finalize() +{ + _ClearNodes(); + SetDelegate(NULL); +} + +void SQTable::Clear() +{ + _ClearNodes(); + _usednodes = 0; + Rehash(true); +} diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqtable.h b/src/modules/app_sqlang/squirrel/squirrel/sqtable.h new file mode 100644 index 00000000000..1b1659c348f --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqtable.h @@ -0,0 +1,110 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQTABLE_H_ +#define _SQTABLE_H_ +/* +* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.) +* http://www.lua.org/copyright.html#4 +* http://www.lua.org/source/4.0.1/src_ltable.c.html +*/ + +#include "sqstring.h" + + +#define hashptr(p) ((SQHash)(((SQInteger)p) >> 3)) + +inline SQHash HashObj(const SQObjectPtr &key) +{ + switch(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; + +/////////////////////////// + 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)); + } +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + SQObjectType GetType() {return OT_TABLE;} +#endif + inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash) + { + _HashNode *n = &_nodes[hash]; + do{ + if(_rawval(n->key) == _rawval(key) && type(n->key) == 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(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); + } + +}; + +#endif //_SQTABLE_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/squirrel.dsp b/src/modules/app_sqlang/squirrel/squirrel/squirrel.dsp new file mode 100644 index 00000000000..4778b696346 --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/squirrel.dsp @@ -0,0 +1,302 @@ +# Microsoft Developer Studio Project File - Name="squirrel" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=squirrel - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "squirrel.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "squirrel.mak" CFG="squirrel - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "squirrel - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "squirrel - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_LocalPath ".." +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "squirrel - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "..\include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "GARBAGE_COLLECTOR" /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"..\lib\squirrel.lib" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"..\lib\squirrel.lib" + +!ENDIF + +# Begin Target + +# Name "squirrel - Win32 Release" +# Name "squirrel - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\sqapi.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sqbaselib.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sqcompiler.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sqdebug.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sqfuncstate.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sqlexer.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sqmem.cpp +# End Source File +# Begin Source File + +SOURCE=.\sqobject.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sqstate.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sqtable.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sqclass.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sqvm.cpp + +!IF "$(CFG)" == "squirrel - Win32 Release" + +!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" + +# ADD CPP /YX"stdafx.h" + +!ENDIF + +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\sqarray.h +# End Source File +# Begin Source File + +SOURCE=.\sqclosure.h +# End Source File +# Begin Source File + +SOURCE=.\sqcompiler.h +# End Source File +# Begin Source File + +SOURCE=.\sqfuncproto.h +# End Source File +# Begin Source File + +SOURCE=.\sqfuncstate.h +# End Source File +# Begin Source File + +SOURCE=.\sqlexer.h +# End Source File +# Begin Source File + +SOURCE=.\sqobject.h +# End Source File +# Begin Source File + +SOURCE=.\sqopcodes.h +# End Source File +# Begin Source File + +SOURCE=.\sqpcheader.h +# End Source File +# Begin Source File + +SOURCE=.\sqstate.h +# End Source File +# Begin Source File + +SOURCE=.\sqstring.h +# End Source File +# Begin Source File + +SOURCE=.\sqtable.h +# End Source File +# Begin Source File + +SOURCE=.\squserdata.h +# End Source File +# Begin Source File + +SOURCE=.\squtils.h +# End Source File +# Begin Source File + +SOURCE=.\sqclass.h +# End Source File +# Begin Source File + +SOURCE=.\sqvm.h +# End Source File +# End Group +# End Target +# End Project diff --git a/src/modules/app_sqlang/squirrel/squirrel/squserdata.h b/src/modules/app_sqlang/squirrel/squirrel/squserdata.h new file mode 100644 index 00000000000..f63411e275c --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/squserdata.h @@ -0,0 +1,40 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQUSERDATA_H_ +#define _SQUSERDATA_H_ + +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; + } +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize(){SetDelegate(NULL);} + SQObjectType GetType(){ return OT_USERDATA;} +#endif + 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]; +}; + +#endif //_SQUSERDATA_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/squtils.h b/src/modules/app_sqlang/squirrel/squirrel/squtils.h new file mode 100644 index 00000000000..41890252e7d --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/squtils.h @@ -0,0 +1,116 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQUTILS_H_ +#define _SQUTILS_H_ + +void *sq_vm_malloc(SQUnsignedInteger size); +void *sq_vm_realloc(void *p,SQUnsignedInteger oldsize,SQUnsignedInteger size); +void sq_vm_free(void *p,SQUnsignedInteger size); + +#define sq_new(__ptr,__type) {__ptr=(__type *)sq_vm_malloc(sizeof(__type));new (__ptr) __type;} +#define sq_delete(__ptr,__type) {__ptr->~__type();sq_vm_free(__ptr,sizeof(__type));} +#define SQ_MALLOC(__size) sq_vm_malloc((__size)); +#define SQ_FREE(__ptr,__size) sq_vm_free((__ptr),(__size)); +#define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc((__ptr),(__oldsize),(__size)); + +#define sq_aligning(v) (((size_t)(v) + (SQ_ALIGNMENT-1)) & (~(SQ_ALIGNMENT-1))) + +//sqvector mini vector class, supports objects by value +template class sqvector +{ +public: + sqvector() + { + _vals = NULL; + _size = 0; + _allocated = 0; + } + sqvector(const sqvector& v) + { + copy(v); + } + void copy(const sqvector& 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; +}; + +#endif //_SQUTILS_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqvm.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqvm.cpp new file mode 100644 index 00000000000..2c9cdc8f4ae --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqvm.cpp @@ -0,0 +1,1748 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include +#include +#include "sqopcodes.h" +#include "sqvm.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "sqstring.h" +#include "sqtable.h" +#include "squserdata.h" +#include "sqarray.h" +#include "sqclass.h" + +#define TOP() (_stack._vals[_top-1]) + +bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2) +{ + SQInteger res; + if((type(o1)|type(o2)) == OT_INTEGER) + { + SQInteger i1 = _integer(o1), i2 = _integer(o2); + switch(op) { + case BW_AND: res = i1 & i2; break; + case BW_OR: res = i1 | i2; break; + case BW_XOR: res = i1 ^ i2; break; + case BW_SHIFTL: res = i1 << i2; break; + case BW_SHIFTR: res = i1 >> i2; break; + case BW_USHIFTR:res = (SQInteger)(*((SQUnsignedInteger*)&i1) >> i2); break; + default: { Raise_Error(_SC("internal vm error bitwise op failed")); return false; } + } + } + else { Raise_Error(_SC("bitwise op between '%s' and '%s'"),GetTypeName(o1),GetTypeName(o2)); return false;} + trg = res; + return true; +} + +#define _ARITH_(op,trg,o1,o2) \ +{ \ + SQInteger tmask = type(o1)|type(o2); \ + switch(tmask) { \ + case OT_INTEGER: trg = _integer(o1) op _integer(o2);break; \ + case (OT_FLOAT|OT_INTEGER): \ + case (OT_FLOAT): trg = tofloat(o1) op tofloat(o2); break;\ + default: _GUARD(ARITH_OP((#op)[0],trg,o1,o2)); break;\ + } \ +} + +#define _ARITH_NOZERO(op,trg,o1,o2,err) \ +{ \ + SQInteger tmask = type(o1)|type(o2); \ + switch(tmask) { \ + case OT_INTEGER: { SQInteger i2 = _integer(o2); if(i2 == 0) { Raise_Error(err); SQ_THROW(); } trg = _integer(o1) op i2; } break;\ + case (OT_FLOAT|OT_INTEGER): \ + case (OT_FLOAT): trg = tofloat(o1) op tofloat(o2); break;\ + default: _GUARD(ARITH_OP((#op)[0],trg,o1,o2)); break;\ + } \ +} + +bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2) +{ + SQInteger tmask = type(o1)|type(o2); + switch(tmask) { + case OT_INTEGER:{ + SQInteger res, i1 = _integer(o1), i2 = _integer(o2); + switch(op) { + case '+': res = i1 + i2; break; + case '-': res = i1 - i2; break; + case '/': if (i2 == 0) { Raise_Error(_SC("division by zero")); return false; } + else if (i2 == -1 && i1 == INT_MIN) { Raise_Error(_SC("integer overflow")); return false; } + res = i1 / i2; + break; + case '*': res = i1 * i2; break; + case '%': if (i2 == 0) { Raise_Error(_SC("modulo by zero")); return false; } + else if (i2 == -1 && i1 == INT_MIN) { res = 0; break; } + res = i1 % i2; + break; + default: res = 0xDEADBEEF; + } + trg = res; } + break; + case (OT_FLOAT|OT_INTEGER): + case (OT_FLOAT):{ + SQFloat res, f1 = tofloat(o1), f2 = tofloat(o2); + switch(op) { + case '+': res = f1 + f2; break; + case '-': res = f1 - f2; break; + case '/': res = f1 / f2; break; + case '*': res = f1 * f2; break; + case '%': res = SQFloat(fmod((double)f1,(double)f2)); break; + default: res = 0x0f; + } + trg = res; } + break; + default: + if(op == '+' && (tmask & _RT_STRING)){ + if(!StringCat(o1, o2, trg)) return false; + } + else if(!ArithMetaMethod(op,o1,o2,trg)) { + return false; + } + } + return true; +} + +SQVM::SQVM(SQSharedState *ss) +{ + _sharedstate=ss; + _suspended = SQFalse; + _suspended_target = -1; + _suspended_root = SQFalse; + _suspended_traps = -1; + _foreignptr = NULL; + _nnativecalls = 0; + _nmetamethodscall = 0; + _lasterror.Null(); + _errorhandler.Null(); + _debughook = false; + _debughook_native = NULL; + _debughook_closure.Null(); + _openouters = NULL; + ci = NULL; + _releasehook = NULL; + INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); +} + +void SQVM::Finalize() +{ + if(_releasehook) { _releasehook(_foreignptr,0); _releasehook = NULL; } + if(_openouters) CloseOuters(&_stack._vals[0]); + _roottable.Null(); + _lasterror.Null(); + _errorhandler.Null(); + _debughook = false; + _debughook_native = NULL; + _debughook_closure.Null(); + temp_reg.Null(); + _callstackdata.resize(0); + SQInteger size=_stack.size(); + for(SQInteger i=0;i_gc_chain,this); +} + +bool SQVM::ArithMetaMethod(SQInteger op,const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &dest) +{ + SQMetaMethod mm; + switch(op){ + case _SC('+'): mm=MT_ADD; break; + case _SC('-'): mm=MT_SUB; break; + case _SC('/'): mm=MT_DIV; break; + case _SC('*'): mm=MT_MUL; break; + case _SC('%'): mm=MT_MODULO; break; + default: mm = MT_ADD; assert(0); break; //shutup compiler + } + if(is_delegable(o1) && _delegable(o1)->_delegate) { + + SQObjectPtr closure; + if(_delegable(o1)->GetMetaMethod(this, mm, closure)) { + Push(o1);Push(o2); + return CallMetaMethod(closure,mm,2,dest); + } + } + Raise_Error(_SC("arith op %c on between '%s' and '%s'"),op,GetTypeName(o1),GetTypeName(o2)); + return false; +} + +bool SQVM::NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o) +{ + + switch(type(o)) { + case OT_INTEGER: + trg = -_integer(o); + return true; + case OT_FLOAT: + trg = -_float(o); + return true; + case OT_TABLE: + case OT_USERDATA: + case OT_INSTANCE: + if(_delegable(o)->_delegate) { + SQObjectPtr closure; + if(_delegable(o)->GetMetaMethod(this, MT_UNM, closure)) { + Push(o); + if(!CallMetaMethod(closure, MT_UNM, 1, temp_reg)) return false; + _Swap(trg,temp_reg); + return true; + + } + } + default:break; //shutup compiler + } + Raise_Error(_SC("attempt to negate a %s"), GetTypeName(o)); + return false; +} + +#define _RET_SUCCEED(exp) { result = (exp); return true; } +bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result) +{ + SQObjectType t1 = type(o1), t2 = type(o2); + if(t1 == t2) { + if(_rawval(o1) == _rawval(o2))_RET_SUCCEED(0); + SQObjectPtr res; + switch(t1){ + case OT_STRING: + _RET_SUCCEED(scstrcmp(_stringval(o1),_stringval(o2))); + case OT_INTEGER: + _RET_SUCCEED((_integer(o1)<_integer(o2))?-1:1); + case OT_FLOAT: + _RET_SUCCEED((_float(o1)<_float(o2))?-1:1); + case OT_TABLE: + case OT_USERDATA: + case OT_INSTANCE: + if(_delegable(o1)->_delegate) { + SQObjectPtr closure; + if(_delegable(o1)->GetMetaMethod(this, MT_CMP, closure)) { + Push(o1);Push(o2); + if(CallMetaMethod(closure,MT_CMP,2,res)) { + if(type(res) != OT_INTEGER) { + Raise_Error(_SC("_cmp must return an integer")); + return false; + } + _RET_SUCCEED(_integer(res)) + } + return false; + } + } + //continues through (no break needed) + default: + _RET_SUCCEED( _userpointer(o1) < _userpointer(o2)?-1:1 ); + } + assert(0); + //if(type(res)!=OT_INTEGER) { Raise_CompareError(o1,o2); return false; } + // _RET_SUCCEED(_integer(res)); + + } + else{ + if(sq_isnumeric(o1) && sq_isnumeric(o2)){ + if((t1==OT_INTEGER) && (t2==OT_FLOAT)) { + if( _integer(o1)==_float(o2) ) { _RET_SUCCEED(0); } + else if( _integer(o1)<_float(o2) ) { _RET_SUCCEED(-1); } + _RET_SUCCEED(1); + } + else{ + if( _float(o1)==_integer(o2) ) { _RET_SUCCEED(0); } + else if( _float(o1)<_integer(o2) ) { _RET_SUCCEED(-1); } + _RET_SUCCEED(1); + } + } + else if(t1==OT_NULL) {_RET_SUCCEED(-1);} + else if(t2==OT_NULL) {_RET_SUCCEED(1);} + else { Raise_CompareError(o1,o2); return false; } + + } + assert(0); + _RET_SUCCEED(0); //cannot happen +} + +bool SQVM::CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res) +{ + SQInteger r; + if(ObjCmp(o1,o2,r)) { + switch(op) { + case CMP_G: res = (r > 0); return true; + case CMP_GE: res = (r >= 0); return true; + case CMP_L: res = (r < 0); return true; + case CMP_LE: res = (r <= 0); return true; + case CMP_3W: res = r; return true; + } + assert(0); + } + return false; +} + +bool SQVM::ToString(const SQObjectPtr &o,SQObjectPtr &res) +{ + switch(type(o)) { + case OT_STRING: + res = o; + return true; + case OT_FLOAT: + scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)),sq_rsl(NUMBER_MAX_CHAR),_SC("%g"),_float(o)); + break; + case OT_INTEGER: + scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)),sq_rsl(NUMBER_MAX_CHAR),_PRINT_INT_FMT,_integer(o)); + break; + case OT_BOOL: + scsprintf(_sp(sq_rsl(6)),sq_rsl(6),_integer(o)?_SC("true"):_SC("false")); + break; + case OT_TABLE: + case OT_USERDATA: + case OT_INSTANCE: + if(_delegable(o)->_delegate) { + SQObjectPtr closure; + if(_delegable(o)->GetMetaMethod(this, MT_TOSTRING, closure)) { + Push(o); + if(CallMetaMethod(closure,MT_TOSTRING,1,res)) {; + if(type(res) == OT_STRING) + return true; + } + else { + return false; + } + } + } + default: + scsprintf(_sp(sq_rsl((sizeof(void*)*2)+NUMBER_MAX_CHAR)),sq_rsl((sizeof(void*)*2)+NUMBER_MAX_CHAR),_SC("(%s : 0x%p)"),GetTypeName(o),(void*)_rawval(o)); + } + res = SQString::Create(_ss(this),_spval); + return true; +} + + +bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr &dest) +{ + SQObjectPtr a, b; + if(!ToString(str, a)) return false; + if(!ToString(obj, b)) return false; + SQInteger l = _string(a)->_len , ol = _string(b)->_len; + SQChar *s = _sp(sq_rsl(l + ol + 1)); + memcpy(s, _stringval(a), sq_rsl(l)); + memcpy(s + l, _stringval(b), sq_rsl(ol)); + dest = SQString::Create(_ss(this), _spval, l + ol); + return true; +} + +bool SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest) +{ + if(is_delegable(obj1) && _delegable(obj1)->_delegate) { + SQObjectPtr closure; + if(_delegable(obj1)->GetMetaMethod(this, MT_TYPEOF, closure)) { + Push(obj1); + return CallMetaMethod(closure,MT_TYPEOF,1,dest); + } + } + dest = SQString::Create(_ss(this),GetTypeName(obj1)); + return true; +} + +bool SQVM::Init(SQVM *friendvm, SQInteger stacksize) +{ + _stack.resize(stacksize); + _alloccallsstacksize = 4; + _callstackdata.resize(_alloccallsstacksize); + _callsstacksize = 0; + _callsstack = &_callstackdata[0]; + _stackbase = 0; + _top = 0; + if(!friendvm) { + _roottable = SQTable::Create(_ss(this), 0); + sq_base_register(this); + } + else { + _roottable = friendvm->_roottable; + _errorhandler = friendvm->_errorhandler; + _debughook = friendvm->_debughook; + _debughook_native = friendvm->_debughook_native; + _debughook_closure = friendvm->_debughook_closure; + } + + + return true; +} + + +bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger args,SQInteger stackbase,bool tailcall) +{ + SQFunctionProto *func = closure->_function; + + SQInteger paramssize = func->_nparameters; + const SQInteger newtop = stackbase + func->_stacksize; + SQInteger nargs = args; + if(func->_varparams) + { + paramssize--; + if (nargs < paramssize) { + Raise_Error(_SC("wrong number of parameters")); + return false; + } + + //dumpstack(stackbase); + SQInteger nvargs = nargs - paramssize; + SQArray *arr = SQArray::Create(_ss(this),nvargs); + SQInteger pbase = stackbase+paramssize; + for(SQInteger n = 0; n < nvargs; n++) { + arr->_values[n] = _stack._vals[pbase]; + _stack._vals[pbase].Null(); + pbase++; + + } + _stack._vals[stackbase+paramssize] = arr; + //dumpstack(stackbase); + } + else if (paramssize != nargs) { + SQInteger ndef = func->_ndefaultparams; + SQInteger diff; + if(ndef && nargs < paramssize && (diff = paramssize - nargs) <= ndef) { + for(SQInteger n = ndef - diff; n < ndef; n++) { + _stack._vals[stackbase + (nargs++)] = closure->_defaultparams[n]; + } + } + else { + Raise_Error(_SC("wrong number of parameters")); + return false; + } + } + + if(closure->_env) { + _stack._vals[stackbase] = closure->_env->_obj; + } + + if(!EnterFrame(stackbase, newtop, tailcall)) return false; + + ci->_closure = closure; + ci->_literals = func->_literals; + ci->_ip = func->_instructions; + ci->_target = (SQInt32)target; + + if (_debughook) { + CallDebugHook(_SC('c')); + } + + if (closure->_function->_bgenerator) { + SQFunctionProto *f = closure->_function; + SQGenerator *gen = SQGenerator::Create(_ss(this), closure); + if(!gen->Yield(this,f->_stacksize)) + return false; + SQObjectPtr temp; + Return(1, target, temp); + STK(target) = gen; + } + + + return true; +} + +bool SQVM::Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval) +{ + SQBool _isroot = ci->_root; + SQInteger callerbase = _stackbase - ci->_prevstkbase; + + if (_debughook) { + for(SQInteger i=0; i_ncalls; i++) { + CallDebugHook(_SC('r')); + } + } + + SQObjectPtr *dest; + if (_isroot) { + dest = &(retval); + } else if (ci->_target == -1) { + dest = NULL; + } else { + dest = &_stack._vals[callerbase + ci->_target]; + } + if (dest) { + if(_arg0 != 0xFF) { + *dest = _stack._vals[_stackbase+_arg1]; + } + else { + dest->Null(); + } + //*dest = (_arg0 != 0xFF) ? _stack._vals[_stackbase+_arg1] : _null_; + } + LeaveFrame(); + return _isroot ? true : false; +} + +#define _RET_ON_FAIL(exp) { if(!exp) return false; } + +bool SQVM::PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr) +{ + SQObjectPtr trg; + _RET_ON_FAIL(ARITH_OP( op , trg, a, incr)); + target = a; + a = trg; + return true; +} + +bool SQVM::DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix,SQInteger selfidx) +{ + SQObjectPtr tmp, tself = self, tkey = key; + if (!Get(tself, tkey, tmp, 0, selfidx)) { return false; } + _RET_ON_FAIL(ARITH_OP( op , target, tmp, incr)) + if (!Set(tself, tkey, target,selfidx)) { return false; } + if (postfix) target = tmp; + return true; +} + +#define arg0 (_i_._arg0) +#define sarg0 ((SQInteger)*((const signed char *)&_i_._arg0)) +#define arg1 (_i_._arg1) +#define sarg1 (*((const SQInt32 *)&_i_._arg1)) +#define arg2 (_i_._arg2) +#define arg3 (_i_._arg3) +#define sarg3 ((SQInteger)*((const signed char *)&_i_._arg3)) + +SQRESULT SQVM::Suspend() +{ + if (_suspended) + return sq_throwerror(this, _SC("cannot suspend an already suspended vm")); + if (_nnativecalls!=2) + return sq_throwerror(this, _SC("cannot suspend through native calls/metamethods")); + return SQ_SUSPEND_FLAG; +} + + +#define _FINISH(howmuchtojump) {jump = howmuchtojump; return true; } +bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr +&o3,SQObjectPtr &o4,SQInteger SQ_UNUSED_ARG(arg_2),int exitpos,int &jump) +{ + SQInteger nrefidx; + switch(type(o1)) { + case OT_TABLE: + if((nrefidx = _table(o1)->Next(false,o4, o2, o3)) == -1) _FINISH(exitpos); + o4 = (SQInteger)nrefidx; _FINISH(1); + case OT_ARRAY: + if((nrefidx = _array(o1)->Next(o4, o2, o3)) == -1) _FINISH(exitpos); + o4 = (SQInteger) nrefidx; _FINISH(1); + case OT_STRING: + if((nrefidx = _string(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos); + o4 = (SQInteger)nrefidx; _FINISH(1); + case OT_CLASS: + if((nrefidx = _class(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos); + o4 = (SQInteger)nrefidx; _FINISH(1); + case OT_USERDATA: + case OT_INSTANCE: + if(_delegable(o1)->_delegate) { + SQObjectPtr itr; + SQObjectPtr closure; + if(_delegable(o1)->GetMetaMethod(this, MT_NEXTI, closure)) { + Push(o1); + Push(o4); + if(CallMetaMethod(closure, MT_NEXTI, 2, itr)) { + o4 = o2 = itr; + if(type(itr) == OT_NULL) _FINISH(exitpos); + if(!Get(o1, itr, o3, 0, DONT_FALL_BACK)) { + Raise_Error(_SC("_nexti returned an invalid idx")); // cloud be changed + return false; + } + _FINISH(1); + } + else { + return false; + } + } + Raise_Error(_SC("_nexti failed")); + return false; + } + break; + case OT_GENERATOR: + if(_generator(o1)->_state == SQGenerator::eDead) _FINISH(exitpos); + if(_generator(o1)->_state == SQGenerator::eSuspended) { + SQInteger idx = 0; + if(type(o4) == OT_INTEGER) { + idx = _integer(o4) + 1; + } + o2 = idx; + o4 = idx; + _generator(o1)->Resume(this, o3); + _FINISH(0); + } + default: + Raise_Error(_SC("cannot iterate %s"), GetTypeName(o1)); + } + return false; //cannot be hit(just to avoid warnings) +} + +#define COND_LITERAL (arg3!=0?ci->_literals[arg1]:STK(arg1)) + +#define SQ_THROW() { goto exception_trap; } + +#define _GUARD(exp) { if(!exp) { SQ_THROW();} } + +bool SQVM::CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func) +{ + SQInteger nouters; + SQClosure *closure = SQClosure::Create(_ss(this), func,_table(_roottable)->GetWeakRef(OT_TABLE)); + if((nouters = func->_noutervalues)) { + for(SQInteger i = 0; i_outervalues[i]; + switch(v._type){ + case otLOCAL: + FindOuter(closure->_outervalues[i], &STK(_integer(v._src))); + break; + case otOUTER: + closure->_outervalues[i] = _closure(ci->_closure)->_outervalues[_integer(v._src)]; + break; + } + } + } + SQInteger ndefparams; + if((ndefparams = func->_ndefaultparams)) { + for(SQInteger i = 0; i < ndefparams; i++) { + SQInteger spos = func->_defaultparams[i]; + closure->_defaultparams[i] = _stack._vals[_stackbase + spos]; + } + } + target = closure; + return true; + +} + + +bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes) +{ + SQClass *base = NULL; + SQObjectPtr attrs; + if(baseclass != -1) { + if(type(_stack._vals[_stackbase+baseclass]) != OT_CLASS) { Raise_Error(_SC("trying to inherit from a %s"),GetTypeName(_stack._vals[_stackbase+baseclass])); return false; } + base = _class(_stack._vals[_stackbase + baseclass]); + } + if(attributes != MAX_FUNC_STACKSIZE) { + attrs = _stack._vals[_stackbase+attributes]; + } + target = SQClass::Create(_ss(this),base); + if(type(_class(target)->_metamethods[MT_INHERITED]) != OT_NULL) { + int nparams = 2; + SQObjectPtr ret; + Push(target); Push(attrs); + if(!Call(_class(target)->_metamethods[MT_INHERITED],nparams,_top - nparams, ret, false)) { + Pop(nparams); + return false; + } + Pop(nparams); + } + _class(target)->_attributes = attrs; + return true; +} + +bool SQVM::IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res) +{ + if(type(o1) == type(o2)) { + res = (_rawval(o1) == _rawval(o2)); + } + else { + if(sq_isnumeric(o1) && sq_isnumeric(o2)) { + res = (tofloat(o1) == tofloat(o2)); + } + else { + res = false; + } + } + return true; +} + +bool SQVM::IsFalse(SQObjectPtr &o) +{ + if(((type(o) & SQOBJECT_CANBEFALSE) + && ( ((type(o) == OT_FLOAT) && (_float(o) == SQFloat(0.0))) )) +#if !defined(SQUSEDOUBLE) || (defined(SQUSEDOUBLE) && defined(_SQ64)) + || (_integer(o) == 0) ) //OT_NULL|OT_INTEGER|OT_BOOL +#else + || (((type(o) != OT_FLOAT) && (_integer(o) == 0))) ) //OT_NULL|OT_INTEGER|OT_BOOL +#endif + { + return true; + } + return false; +} +extern SQInstructionDesc g_InstrDesc[]; +bool SQVM::Execute(SQObjectPtr &closure, SQInteger nargs, SQInteger stackbase,SQObjectPtr &outres, SQBool raiseerror,ExecutionType et) +{ + if ((_nnativecalls + 1) > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; } + _nnativecalls++; + AutoDec ad(&_nnativecalls); + SQInteger traps = 0; + CallInfo *prevci = ci; + + switch(et) { + case ET_CALL: { + temp_reg = closure; + if(!StartCall(_closure(temp_reg), _top - nargs, nargs, stackbase, false)) { + //call the handler if there are no calls in the stack, if not relies on the previous node + if(ci == NULL) CallErrorHandler(_lasterror); + return false; + } + if(ci == prevci) { + outres = STK(_top-nargs); + return true; + } + ci->_root = SQTrue; + } + break; + case ET_RESUME_GENERATOR: _generator(closure)->Resume(this, outres); ci->_root = SQTrue; traps += ci->_etraps; break; + case ET_RESUME_VM: + case ET_RESUME_THROW_VM: + traps = _suspended_traps; + ci->_root = _suspended_root; + _suspended = SQFalse; + if(et == ET_RESUME_THROW_VM) { SQ_THROW(); } + break; + } + +exception_restore: + // + { + for(;;) + { + const SQInstruction &_i_ = *ci->_ip++; + //dumpstack(_stackbase); + //scprintf("\n[%d] %s %d %d %d %d\n",ci->_ip-_closure(ci->_closure)->_function->_instructions,g_InstrDesc[_i_.op].name,arg0,arg1,arg2,arg3); + switch(_i_.op) + { + case _OP_LINE: if (_debughook) CallDebugHook(_SC('l'),arg1); continue; + case _OP_LOAD: TARGET = ci->_literals[arg1]; continue; + case _OP_LOADINT: +#ifndef _SQ64 + TARGET = (SQInteger)arg1; continue; +#else + TARGET = (SQInteger)((SQInt32)arg1); continue; +#endif + case _OP_LOADFLOAT: TARGET = *((const SQFloat *)&arg1); continue; + case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue; + case _OP_TAILCALL:{ + SQObjectPtr &t = STK(arg1); + if (type(t) == OT_CLOSURE + && (!_closure(t)->_function->_bgenerator)){ + SQObjectPtr clo = t; + if(_openouters) CloseOuters(&(_stack._vals[_stackbase])); + for (SQInteger i = 0; i < arg3; i++) STK(i) = STK(arg2 + i); + _GUARD(StartCall(_closure(clo), ci->_target, arg3, _stackbase, true)); + continue; + } + } + case _OP_CALL: { + SQObjectPtr clo = STK(arg1); + switch (type(clo)) { + case OT_CLOSURE: + _GUARD(StartCall(_closure(clo), sarg0, arg3, _stackbase+arg2, false)); + continue; + case OT_NATIVECLOSURE: { + bool suspend; + _GUARD(CallNative(_nativeclosure(clo), arg3, _stackbase+arg2, clo,suspend)); + if(suspend){ + _suspended = SQTrue; + _suspended_target = sarg0; + _suspended_root = ci->_root; + _suspended_traps = traps; + outres = clo; + return true; + } + if(sarg0 != -1) { + STK(arg0) = clo; + } + } + continue; + case OT_CLASS:{ + SQObjectPtr inst; + _GUARD(CreateClassInstance(_class(clo),inst,clo)); + if(sarg0 != -1) { + STK(arg0) = inst; + } + SQInteger stkbase; + switch(type(clo)) { + case OT_CLOSURE: + stkbase = _stackbase+arg2; + _stack._vals[stkbase] = inst; + _GUARD(StartCall(_closure(clo), -1, arg3, stkbase, false)); + break; + case OT_NATIVECLOSURE: + bool suspend; + stkbase = _stackbase+arg2; + _stack._vals[stkbase] = inst; + _GUARD(CallNative(_nativeclosure(clo), arg3, stkbase, clo,suspend)); + break; + default: break; //shutup GCC 4.x + } + } + break; + case OT_TABLE: + case OT_USERDATA: + case OT_INSTANCE:{ + SQObjectPtr closure; + if(_delegable(clo)->_delegate && _delegable(clo)->GetMetaMethod(this,MT_CALL,closure)) { + Push(clo); + for (SQInteger i = 0; i < arg3; i++) Push(STK(arg2 + i)); + if(!CallMetaMethod(closure, MT_CALL, arg3+1, clo)) SQ_THROW(); + if(sarg0 != -1) { + STK(arg0) = clo; + } + break; + } + + //Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo)); + //SQ_THROW(); + } + default: + Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo)); + SQ_THROW(); + } + } + continue; + case _OP_PREPCALL: + case _OP_PREPCALLK: { + SQObjectPtr &key = _i_.op == _OP_PREPCALLK?(ci->_literals)[arg1]:STK(arg1); + SQObjectPtr &o = STK(arg2); + if (!Get(o, key, temp_reg,0,arg2)) { + SQ_THROW(); + } + STK(arg3) = o; + _Swap(TARGET,temp_reg);//TARGET = temp_reg; + } + continue; + case _OP_GETK: + if (!Get(STK(arg2), ci->_literals[arg1], temp_reg, 0,arg2)) { SQ_THROW();} + _Swap(TARGET,temp_reg);//TARGET = temp_reg; + continue; + case _OP_MOVE: TARGET = STK(arg1); continue; + case _OP_NEWSLOT: + _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),false)); + if(arg0 != 0xFF) TARGET = STK(arg3); + continue; + case _OP_DELETE: _GUARD(DeleteSlot(STK(arg1), STK(arg2), TARGET)); continue; + case _OP_SET: + if (!Set(STK(arg1), STK(arg2), STK(arg3),arg1)) { SQ_THROW(); } + if (arg0 != 0xFF) TARGET = STK(arg3); + continue; + case _OP_GET: + if (!Get(STK(arg1), STK(arg2), temp_reg, 0,arg1)) { SQ_THROW(); } + _Swap(TARGET,temp_reg);//TARGET = temp_reg; + continue; + case _OP_EQ:{ + bool res; + if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); } + TARGET = res?true:false; + }continue; + case _OP_NE:{ + bool res; + if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); } + TARGET = (!res)?true:false; + } continue; + case _OP_ADD: _ARITH_(+,TARGET,STK(arg2),STK(arg1)); continue; + case _OP_SUB: _ARITH_(-,TARGET,STK(arg2),STK(arg1)); continue; + case _OP_MUL: _ARITH_(*,TARGET,STK(arg2),STK(arg1)); continue; + case _OP_DIV: _ARITH_NOZERO(/,TARGET,STK(arg2),STK(arg1),_SC("division by zero")); continue; + case _OP_MOD: ARITH_OP('%',TARGET,STK(arg2),STK(arg1)); continue; + case _OP_BITW: _GUARD(BW_OP( arg3,TARGET,STK(arg2),STK(arg1))); continue; + case _OP_RETURN: + if((ci)->_generator) { + (ci)->_generator->Kill(); + } + if(Return(arg0, arg1, temp_reg)){ + assert(traps==0); + //outres = temp_reg; + _Swap(outres,temp_reg); + return true; + } + continue; + case _OP_LOADNULLS:{ for(SQInt32 n=0; n < arg1; n++) STK(arg0+n).Null(); }continue; + case _OP_LOADROOT: { + SQWeakRef *w = _closure(ci->_closure)->_root; + if(type(w->_obj) != OT_NULL) { + TARGET = w->_obj; + } else { + TARGET = _roottable; //shoud this be like this? or null + } + } + continue; + case _OP_LOADBOOL: TARGET = arg1?true:false; continue; + case _OP_DMOVE: STK(arg0) = STK(arg1); STK(arg2) = STK(arg3); continue; + case _OP_JMP: ci->_ip += (sarg1); continue; + //case _OP_JNZ: if(!IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue; + case _OP_JCMP: + _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg0),temp_reg)); + if(IsFalse(temp_reg)) ci->_ip+=(sarg1); + continue; + case _OP_JZ: if(IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue; + case _OP_GETOUTER: { + SQClosure *cur_cls = _closure(ci->_closure); + SQOuter *otr = _outer(cur_cls->_outervalues[arg1]); + TARGET = *(otr->_valptr); + } + continue; + case _OP_SETOUTER: { + SQClosure *cur_cls = _closure(ci->_closure); + SQOuter *otr = _outer(cur_cls->_outervalues[arg1]); + *(otr->_valptr) = STK(arg2); + if(arg0 != 0xFF) { + TARGET = STK(arg2); + } + } + continue; + case _OP_NEWOBJ: + switch(arg3) { + case NOT_TABLE: TARGET = SQTable::Create(_ss(this), arg1); continue; + case NOT_ARRAY: TARGET = SQArray::Create(_ss(this), 0); _array(TARGET)->Reserve(arg1); continue; + case NOT_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue; + default: assert(0); continue; + } + case _OP_APPENDARRAY: + { + SQObject val; + val._unVal.raw = 0; + switch(arg2) { + case AAT_STACK: + val = STK(arg1); break; + case AAT_LITERAL: + val = ci->_literals[arg1]; break; + case AAT_INT: + val._type = OT_INTEGER; +#ifndef _SQ64 + val._unVal.nInteger = (SQInteger)arg1; +#else + val._unVal.nInteger = (SQInteger)((SQInt32)arg1); +#endif + break; + case AAT_FLOAT: + val._type = OT_FLOAT; + val._unVal.fFloat = *((const SQFloat *)&arg1); + break; + case AAT_BOOL: + val._type = OT_BOOL; + val._unVal.nInteger = arg1; + break; + default: val._type = OT_INTEGER; assert(0); break; + + } + _array(STK(arg0))->Append(val); continue; + } + case _OP_COMPARITH: { + SQInteger selfidx = (((SQUnsignedInteger)arg1&0xFFFF0000)>>16); + _GUARD(DerefInc(arg3, TARGET, STK(selfidx), STK(arg2), STK(arg1&0x0000FFFF), false, selfidx)); + } + continue; + case _OP_INC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, false, arg1));} continue; + case _OP_INCL: { + SQObjectPtr &a = STK(arg1); + if(type(a) == OT_INTEGER) { + a._unVal.nInteger = _integer(a) + sarg3; + } + else { + SQObjectPtr o(sarg3); //_GUARD(LOCAL_INC('+',TARGET, STK(arg1), o)); + _ARITH_(+,a,a,o); + } + } continue; + case _OP_PINC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, true, arg1));} continue; + case _OP_PINCL: { + SQObjectPtr &a = STK(arg1); + if(type(a) == OT_INTEGER) { + TARGET = a; + a._unVal.nInteger = _integer(a) + sarg3; + } + else { + SQObjectPtr o(sarg3); _GUARD(PLOCAL_INC('+',TARGET, STK(arg1), o)); + } + + } continue; + case _OP_CMP: _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg1),TARGET)) continue; + case _OP_EXISTS: TARGET = Get(STK(arg1), STK(arg2), temp_reg, GET_FLAG_DO_NOT_RAISE_ERROR | GET_FLAG_RAW, DONT_FALL_BACK) ? true : false; continue; + case _OP_INSTANCEOF: + if(type(STK(arg1)) != OT_CLASS) + {Raise_Error(_SC("cannot apply instanceof between a %s and a %s"),GetTypeName(STK(arg1)),GetTypeName(STK(arg2))); SQ_THROW();} + TARGET = (type(STK(arg2)) == OT_INSTANCE) ? (_instance(STK(arg2))->InstanceOf(_class(STK(arg1)))?true:false) : false; + continue; + case _OP_AND: + if(IsFalse(STK(arg2))) { + TARGET = STK(arg2); + ci->_ip += (sarg1); + } + continue; + case _OP_OR: + if(!IsFalse(STK(arg2))) { + TARGET = STK(arg2); + ci->_ip += (sarg1); + } + continue; + case _OP_NEG: _GUARD(NEG_OP(TARGET,STK(arg1))); continue; + case _OP_NOT: TARGET = IsFalse(STK(arg1)); continue; + case _OP_BWNOT: + if(type(STK(arg1)) == OT_INTEGER) { + SQInteger t = _integer(STK(arg1)); + TARGET = SQInteger(~t); + continue; + } + Raise_Error(_SC("attempt to perform a bitwise op on a %s"), GetTypeName(STK(arg1))); + SQ_THROW(); + case _OP_CLOSURE: { + SQClosure *c = ci->_closure._unVal.pClosure; + SQFunctionProto *fp = c->_function; + if(!CLOSURE_OP(TARGET,fp->_functions[arg1]._unVal.pFunctionProto)) { SQ_THROW(); } + continue; + } + case _OP_YIELD:{ + if(ci->_generator) { + if(sarg1 != MAX_FUNC_STACKSIZE) temp_reg = STK(arg1); + _GUARD(ci->_generator->Yield(this,arg2)); + traps -= ci->_etraps; + if(sarg1 != MAX_FUNC_STACKSIZE) _Swap(STK(arg1),temp_reg);//STK(arg1) = temp_reg; + } + else { Raise_Error(_SC("trying to yield a '%s',only genenerator can be yielded"), GetTypeName(ci->_generator)); SQ_THROW();} + if(Return(arg0, arg1, temp_reg)){ + assert(traps == 0); + outres = temp_reg; + return true; + } + + } + continue; + case _OP_RESUME: + if(type(STK(arg1)) != OT_GENERATOR){ Raise_Error(_SC("trying to resume a '%s',only genenerator can be resumed"), GetTypeName(STK(arg1))); SQ_THROW();} + _GUARD(_generator(STK(arg1))->Resume(this, TARGET)); + traps += ci->_etraps; + continue; + case _OP_FOREACH:{ int tojump; + _GUARD(FOREACH_OP(STK(arg0),STK(arg2),STK(arg2+1),STK(arg2+2),arg2,sarg1,tojump)); + ci->_ip += tojump; } + continue; + case _OP_POSTFOREACH: + assert(type(STK(arg0)) == OT_GENERATOR); + if(_generator(STK(arg0))->_state == SQGenerator::eDead) + ci->_ip += (sarg1 - 1); + continue; + case _OP_CLONE: _GUARD(Clone(STK(arg1), TARGET)); continue; + case _OP_TYPEOF: _GUARD(TypeOf(STK(arg1), TARGET)) continue; + case _OP_PUSHTRAP:{ + SQInstruction *_iv = _closure(ci->_closure)->_function->_instructions; + _etraps.push_back(SQExceptionTrap(_top,_stackbase, &_iv[(ci->_ip-_iv)+arg1], arg0)); traps++; + ci->_etraps++; + } + continue; + case _OP_POPTRAP: { + for(SQInteger i = 0; i < arg0; i++) { + _etraps.pop_back(); traps--; + ci->_etraps--; + } + } + continue; + case _OP_THROW: Raise_Error(TARGET); SQ_THROW(); continue; + case _OP_NEWSLOTA: + _GUARD(NewSlotA(STK(arg1),STK(arg2),STK(arg3),(arg0&NEW_SLOT_ATTRIBUTES_FLAG) ? STK(arg2-1) : SQObjectPtr(),(arg0&NEW_SLOT_STATIC_FLAG)?true:false,false)); + continue; + case _OP_GETBASE:{ + SQClosure *clo = _closure(ci->_closure); + if(clo->_base) { + TARGET = clo->_base; + } + else { + TARGET.Null(); + } + continue; + } + case _OP_CLOSE: + if(_openouters) CloseOuters(&(STK(arg1))); + continue; + } + + } + } +exception_trap: + { + SQObjectPtr currerror = _lasterror; +// dumpstack(_stackbase); +// SQInteger n = 0; + SQInteger last_top = _top; + + if(_ss(this)->_notifyallexceptions || (!traps && raiseerror)) CallErrorHandler(currerror); + + while( ci ) { + if(ci->_etraps > 0) { + SQExceptionTrap &et = _etraps.top(); + ci->_ip = et._ip; + _top = et._stacksize; + _stackbase = et._stackbase; + _stack._vals[_stackbase + et._extarget] = currerror; + _etraps.pop_back(); traps--; ci->_etraps--; + while(last_top >= _top) _stack._vals[last_top--].Null(); + goto exception_restore; + } + else if (_debughook) { + //notify debugger of a "return" + //even if it really an exception unwinding the stack + for(SQInteger i = 0; i < ci->_ncalls; i++) { + CallDebugHook(_SC('r')); + } + } + if(ci->_generator) ci->_generator->Kill(); + bool mustbreak = ci && ci->_root; + LeaveFrame(); + if(mustbreak) break; + } + + _lasterror = currerror; + return false; + } + assert(0); +} + +bool SQVM::CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor) +{ + inst = theclass->CreateInstance(); + if(!theclass->GetConstructor(constructor)) { + constructor.Null(); + } + return true; +} + +void SQVM::CallErrorHandler(SQObjectPtr &error) +{ + if(type(_errorhandler) != OT_NULL) { + SQObjectPtr out; + Push(_roottable); Push(error); + Call(_errorhandler, 2, _top-2, out,SQFalse); + Pop(2); + } +} + + +void SQVM::CallDebugHook(SQInteger type,SQInteger forcedline) +{ + _debughook = false; + SQFunctionProto *func=_closure(ci->_closure)->_function; + if(_debughook_native) { + const SQChar *src = type(func->_sourcename) == OT_STRING?_stringval(func->_sourcename):NULL; + const SQChar *fname = type(func->_name) == OT_STRING?_stringval(func->_name):NULL; + SQInteger line = forcedline?forcedline:func->GetLine(ci->_ip); + _debughook_native(this,type,src,line,fname); + } + else { + SQObjectPtr temp_reg; + SQInteger nparams=5; + Push(_roottable); Push(type); Push(func->_sourcename); Push(forcedline?forcedline:func->GetLine(ci->_ip)); Push(func->_name); + Call(_debughook_closure,nparams,_top-nparams,temp_reg,SQFalse); + Pop(nparams); + } + _debughook = true; +} + +bool SQVM::CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger newbase, SQObjectPtr &retval, bool &suspend) +{ + SQInteger nparamscheck = nclosure->_nparamscheck; + SQInteger newtop = newbase + nargs + nclosure->_noutervalues; + + if (_nnativecalls + 1 > MAX_NATIVE_CALLS) { + Raise_Error(_SC("Native stack overflow")); + return false; + } + + if(nparamscheck && (((nparamscheck > 0) && (nparamscheck != nargs)) || + ((nparamscheck < 0) && (nargs < (-nparamscheck))))) + { + Raise_Error(_SC("wrong number of parameters")); + return false; + } + + SQInteger tcs; + SQIntVec &tc = nclosure->_typecheck; + if((tcs = tc.size())) { + for(SQInteger i = 0; i < nargs && i < tcs; i++) { + if((tc._vals[i] != -1) && !(type(_stack._vals[newbase+i]) & tc._vals[i])) { + Raise_ParamTypeError(i,tc._vals[i],type(_stack._vals[newbase+i])); + return false; + } + } + } + + if(!EnterFrame(newbase, newtop, false)) return false; + ci->_closure = nclosure; + + SQInteger outers = nclosure->_noutervalues; + for (SQInteger i = 0; i < outers; i++) { + _stack._vals[newbase+nargs+i] = nclosure->_outervalues[i]; + } + if(nclosure->_env) { + _stack._vals[newbase] = nclosure->_env->_obj; + } + + _nnativecalls++; + SQInteger ret = (nclosure->_function)(this); + _nnativecalls--; + + suspend = false; + if (ret == SQ_SUSPEND_FLAG) { + suspend = true; + } + else if (ret < 0) { + LeaveFrame(); + Raise_Error(_lasterror); + return false; + } + if(ret) { + retval = _stack._vals[_top-1]; + } + else { + retval.Null(); + } + //retval = ret ? _stack._vals[_top-1] : _null_; + LeaveFrame(); + return true; +} + +#define FALLBACK_OK 0 +#define FALLBACK_NO_MATCH 1 +#define FALLBACK_ERROR 2 + +bool SQVM::Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, SQUnsignedInteger getflags, SQInteger selfidx) +{ + switch(type(self)){ + case OT_TABLE: + if(_table(self)->Get(key,dest))return true; + break; + case OT_ARRAY: + if (sq_isnumeric(key)) { if (_array(self)->Get(tointeger(key), dest)) { return true; } if ((getflags & GET_FLAG_DO_NOT_RAISE_ERROR) == 0) Raise_IdxError(key); return false; } + break; + case OT_INSTANCE: + if(_instance(self)->Get(key,dest)) return true; + break; + case OT_CLASS: + if(_class(self)->Get(key,dest)) return true; + break; + case OT_STRING: + if(sq_isnumeric(key)){ + SQInteger n = tointeger(key); + SQInteger len = _string(self)->_len; + if (n < 0) { n += len; } + if (n >= 0 && n < len) { + dest = SQInteger(_stringval(self)[n]); + return true; + } + if ((getflags & GET_FLAG_DO_NOT_RAISE_ERROR) == 0) Raise_IdxError(key); + return false; + } + break; + default:break; //shut up compiler + } + if ((getflags & GET_FLAG_RAW) == 0) { + switch(FallBackGet(self,key,dest)) { + case FALLBACK_OK: return true; //okie + case FALLBACK_NO_MATCH: break; //keep falling back + case FALLBACK_ERROR: return false; // the metamethod failed + } + if(InvokeDefaultDelegate(self,key,dest)) { + return true; + } + } +//#ifdef ROOT_FALLBACK + if(selfidx == 0) { + SQWeakRef *w = _closure(ci->_closure)->_root; + if(type(w->_obj) != OT_NULL) + { + if(Get(*((const SQObjectPtr *)&w->_obj),key,dest,0,DONT_FALL_BACK)) return true; + } + + } +//#endif + if ((getflags & GET_FLAG_DO_NOT_RAISE_ERROR) == 0) Raise_IdxError(key); + return false; +} + +bool SQVM::InvokeDefaultDelegate(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest) +{ + SQTable *ddel = NULL; + switch(type(self)) { + case OT_CLASS: ddel = _class_ddel; break; + case OT_TABLE: ddel = _table_ddel; break; + case OT_ARRAY: ddel = _array_ddel; break; + case OT_STRING: ddel = _string_ddel; break; + case OT_INSTANCE: ddel = _instance_ddel; break; + case OT_INTEGER:case OT_FLOAT:case OT_BOOL: ddel = _number_ddel; break; + case OT_GENERATOR: ddel = _generator_ddel; break; + case OT_CLOSURE: case OT_NATIVECLOSURE: ddel = _closure_ddel; break; + case OT_THREAD: ddel = _thread_ddel; break; + case OT_WEAKREF: ddel = _weakref_ddel; break; + default: return false; + } + return ddel->Get(key,dest); +} + + +SQInteger SQVM::FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest) +{ + switch(type(self)){ + case OT_TABLE: + case OT_USERDATA: + //delegation + if(_delegable(self)->_delegate) { + if(Get(SQObjectPtr(_delegable(self)->_delegate),key,dest,0,DONT_FALL_BACK)) return FALLBACK_OK; + } + else { + return FALLBACK_NO_MATCH; + } + //go through + case OT_INSTANCE: { + SQObjectPtr closure; + if(_delegable(self)->GetMetaMethod(this, MT_GET, closure)) { + Push(self);Push(key); + _nmetamethodscall++; + AutoDec ad(&_nmetamethodscall); + if(Call(closure, 2, _top - 2, dest, SQFalse)) { + Pop(2); + return FALLBACK_OK; + } + else { + Pop(2); + if(type(_lasterror) != OT_NULL) { //NULL means "clean failure" (not found) + return FALLBACK_ERROR; + } + } + } + } + break; + default: break;//shutup GCC 4.x + } + // no metamethod or no fallback type + return FALLBACK_NO_MATCH; +} + +bool SQVM::Set(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,SQInteger selfidx) +{ + switch(type(self)){ + case OT_TABLE: + if(_table(self)->Set(key,val)) return true; + break; + case OT_INSTANCE: + if(_instance(self)->Set(key,val)) return true; + break; + case OT_ARRAY: + if(!sq_isnumeric(key)) { Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); return false; } + if(!_array(self)->Set(tointeger(key),val)) { + Raise_IdxError(key); + return false; + } + return true; + default: + Raise_Error(_SC("trying to set '%s'"),GetTypeName(self)); + return false; + } + + switch(FallBackSet(self,key,val)) { + case FALLBACK_OK: return true; //okie + case FALLBACK_NO_MATCH: break; //keep falling back + case FALLBACK_ERROR: return false; // the metamethod failed + } + if(selfidx == 0) { + if(_table(_roottable)->Set(key,val)) + return true; + } + Raise_IdxError(key); + return false; +} + +SQInteger SQVM::FallBackSet(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val) +{ + switch(type(self)) { + case OT_TABLE: + if(_table(self)->_delegate) { + if(Set(_table(self)->_delegate,key,val,DONT_FALL_BACK)) return FALLBACK_OK; + } + //keps on going + case OT_INSTANCE: + case OT_USERDATA:{ + SQObjectPtr closure; + SQObjectPtr t; + if(_delegable(self)->GetMetaMethod(this, MT_SET, closure)) { + Push(self);Push(key);Push(val); + _nmetamethodscall++; + AutoDec ad(&_nmetamethodscall); + if(Call(closure, 3, _top - 3, t, SQFalse)) { + Pop(3); + return FALLBACK_OK; + } + else { + if(type(_lasterror) != OT_NULL) { //NULL means "clean failure" (not found) + //error + Pop(3); + return FALLBACK_ERROR; + } + } + } + } + break; + default: break;//shutup GCC 4.x + } + // no metamethod or no fallback type + return FALLBACK_NO_MATCH; +} + +bool SQVM::Clone(const SQObjectPtr &self,SQObjectPtr &target) +{ + SQObjectPtr temp_reg; + SQObjectPtr newobj; + switch(type(self)){ + case OT_TABLE: + newobj = _table(self)->Clone(); + goto cloned_mt; + case OT_INSTANCE: { + newobj = _instance(self)->Clone(_ss(this)); +cloned_mt: + SQObjectPtr closure; + if(_delegable(newobj)->_delegate && _delegable(newobj)->GetMetaMethod(this,MT_CLONED,closure)) { + Push(newobj); + Push(self); + if(!CallMetaMethod(closure,MT_CLONED,2,temp_reg)) + return false; + } + } + target = newobj; + return true; + case OT_ARRAY: + target = _array(self)->Clone(); + return true; + default: + Raise_Error(_SC("cloning a %s"), GetTypeName(self)); + return false; + } +} + +bool SQVM::NewSlotA(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,const SQObjectPtr &attrs,bool bstatic,bool raw) +{ + if(type(self) != OT_CLASS) { + Raise_Error(_SC("object must be a class")); + return false; + } + SQClass *c = _class(self); + if(!raw) { + SQObjectPtr &mm = c->_metamethods[MT_NEWMEMBER]; + if(type(mm) != OT_NULL ) { + Push(self); Push(key); Push(val); + Push(attrs); + Push(bstatic); + return CallMetaMethod(mm,MT_NEWMEMBER,5,temp_reg); + } + } + if(!NewSlot(self, key, val,bstatic)) + return false; + if(type(attrs) != OT_NULL) { + c->SetAttributes(key,attrs); + } + return true; +} + +bool SQVM::NewSlot(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic) +{ + if(type(key) == OT_NULL) { Raise_Error(_SC("null cannot be used as index")); return false; } + switch(type(self)) { + case OT_TABLE: { + bool rawcall = true; + if(_table(self)->_delegate) { + SQObjectPtr res; + if(!_table(self)->Get(key,res)) { + SQObjectPtr closure; + if(_delegable(self)->_delegate && _delegable(self)->GetMetaMethod(this,MT_NEWSLOT,closure)) { + Push(self);Push(key);Push(val); + if(!CallMetaMethod(closure,MT_NEWSLOT,3,res)) { + return false; + } + rawcall = false; + } + else { + rawcall = true; + } + } + } + if(rawcall) _table(self)->NewSlot(key,val); //cannot fail + + break;} + case OT_INSTANCE: { + SQObjectPtr res; + SQObjectPtr closure; + if(_delegable(self)->_delegate && _delegable(self)->GetMetaMethod(this,MT_NEWSLOT,closure)) { + Push(self);Push(key);Push(val); + if(!CallMetaMethod(closure,MT_NEWSLOT,3,res)) { + return false; + } + break; + } + Raise_Error(_SC("class instances do not support the new slot operator")); + return false; + break;} + case OT_CLASS: + if(!_class(self)->NewSlot(_ss(this),key,val,bstatic)) { + if(_class(self)->_locked) { + Raise_Error(_SC("trying to modify a class that has already been instantiated")); + return false; + } + else { + SQObjectPtr oval = PrintObjVal(key); + Raise_Error(_SC("the property '%s' already exists"),_stringval(oval)); + return false; + } + } + break; + default: + Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); + return false; + break; + } + return true; +} + + + +bool SQVM::DeleteSlot(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &res) +{ + switch(type(self)) { + case OT_TABLE: + case OT_INSTANCE: + case OT_USERDATA: { + SQObjectPtr t; + //bool handled = false; + SQObjectPtr closure; + if(_delegable(self)->_delegate && _delegable(self)->GetMetaMethod(this,MT_DELSLOT,closure)) { + Push(self);Push(key); + return CallMetaMethod(closure,MT_DELSLOT,2,res); + } + else { + if(type(self) == OT_TABLE) { + if(_table(self)->Get(key,t)) { + _table(self)->Remove(key); + } + else { + Raise_IdxError((const SQObject &)key); + return false; + } + } + else { + Raise_Error(_SC("cannot delete a slot from %s"),GetTypeName(self)); + return false; + } + } + res = t; + } + break; + default: + Raise_Error(_SC("attempt to delete a slot from a %s"),GetTypeName(self)); + return false; + } + return true; +} + +bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObjectPtr &outres,SQBool raiseerror) +{ +#ifdef _DEBUG +SQInteger prevstackbase = _stackbase; +#endif + switch(type(closure)) { + case OT_CLOSURE: + return Execute(closure, nparams, stackbase, outres, raiseerror); + break; + case OT_NATIVECLOSURE:{ + bool suspend; + return CallNative(_nativeclosure(closure), nparams, stackbase, outres,suspend); + + } + break; + case OT_CLASS: { + SQObjectPtr constr; + SQObjectPtr temp; + CreateClassInstance(_class(closure),outres,constr); + SQObjectType ctype = type(constr); + if (ctype == OT_NATIVECLOSURE || ctype == OT_CLOSURE) { + _stack[stackbase] = outres; + return Call(constr,nparams,stackbase,temp,raiseerror); + } + return true; + } + break; + default: + return false; + } +#ifdef _DEBUG + if(!_suspended) { + assert(_stackbase == prevstackbase); + } +#endif + return true; +} + +bool SQVM::CallMetaMethod(SQObjectPtr &closure,SQMetaMethod SQ_UNUSED_ARG(mm),SQInteger nparams,SQObjectPtr &outres) +{ + //SQObjectPtr closure; + + _nmetamethodscall++; + if(Call(closure, nparams, _top - nparams, outres, SQFalse)) { + _nmetamethodscall--; + Pop(nparams); + return true; + } + _nmetamethodscall--; + //} + Pop(nparams); + return false; +} + +void SQVM::FindOuter(SQObjectPtr &target, SQObjectPtr *stackindex) +{ + SQOuter **pp = &_openouters; + SQOuter *p; + SQOuter *otr; + + while ((p = *pp) != NULL && p->_valptr >= stackindex) { + if (p->_valptr == stackindex) { + target = SQObjectPtr(p); + return; + } + pp = &p->_next; + } + otr = SQOuter::Create(_ss(this), stackindex); + otr->_next = *pp; + otr->_idx = (stackindex - _stack._vals); + __ObjAddRef(otr); + *pp = otr; + target = SQObjectPtr(otr); +} + +bool SQVM::EnterFrame(SQInteger newbase, SQInteger newtop, bool tailcall) +{ + if( !tailcall ) { + if( _callsstacksize == _alloccallsstacksize ) { + GrowCallStack(); + } + ci = &_callsstack[_callsstacksize++]; + ci->_prevstkbase = (SQInt32)(newbase - _stackbase); + ci->_prevtop = (SQInt32)(_top - _stackbase); + ci->_etraps = 0; + ci->_ncalls = 1; + ci->_generator = NULL; + ci->_root = SQFalse; + } + else { + ci->_ncalls++; + } + + _stackbase = newbase; + _top = newtop; + if(newtop + MIN_STACK_OVERHEAD > (SQInteger)_stack.size()) { + if(_nmetamethodscall) { + Raise_Error(_SC("stack overflow, cannot resize stack while in a metamethod")); + return false; + } + _stack.resize(newtop + (MIN_STACK_OVERHEAD << 2)); + RelocateOuters(); + } + return true; +} + +void SQVM::LeaveFrame() { + SQInteger last_top = _top; + SQInteger last_stackbase = _stackbase; + SQInteger css = --_callsstacksize; + + /* First clean out the call stack frame */ + ci->_closure.Null(); + _stackbase -= ci->_prevstkbase; + _top = _stackbase + ci->_prevtop; + ci = (css) ? &_callsstack[css-1] : NULL; + + if(_openouters) CloseOuters(&(_stack._vals[last_stackbase])); + while (last_top >= _top) { + _stack._vals[last_top--].Null(); + } +} + +void SQVM::RelocateOuters() +{ + SQOuter *p = _openouters; + while (p) { + p->_valptr = _stack._vals + p->_idx; + p = p->_next; + } +} + +void SQVM::CloseOuters(SQObjectPtr *stackindex) { + SQOuter *p; + while ((p = _openouters) != NULL && p->_valptr >= stackindex) { + p->_value = *(p->_valptr); + p->_valptr = &p->_value; + _openouters = p->_next; + __ObjRelease(p); + } +} + +void SQVM::Remove(SQInteger n) { + n = (n >= 0)?n + _stackbase - 1:_top + n; + for(SQInteger i = n; i < _top; i++){ + _stack[i] = _stack[i+1]; + } + _stack[_top].Null(); + _top--; +} + +void SQVM::Pop() { + _stack[--_top].Null(); +} + +void SQVM::Pop(SQInteger n) { + for(SQInteger i = 0; i < n; i++){ + _stack[--_top].Null(); + } +} + +void SQVM::PushNull() { _stack[_top++].Null(); } +void SQVM::Push(const SQObjectPtr &o) { _stack[_top++] = o; } +SQObjectPtr &SQVM::Top() { return _stack[_top-1]; } +SQObjectPtr &SQVM::PopGet() { return _stack[--_top]; } +SQObjectPtr &SQVM::GetUp(SQInteger n) { return _stack[_top+n]; } +SQObjectPtr &SQVM::GetAt(SQInteger n) { return _stack[n]; } + +#ifdef _DEBUG_DUMP +void SQVM::dumpstack(SQInteger stackbase,bool dumpall) +{ + SQInteger size=dumpall?_stack.size():_top; + SQInteger n=0; + scprintf(_SC("\n>>>>stack dump<<<<\n")); + CallInfo &ci=_callsstack[_callsstacksize-1]; + scprintf(_SC("IP: %p\n"),ci._ip); + scprintf(_SC("prev stack base: %d\n"),ci._prevstkbase); + scprintf(_SC("prev top: %d\n"),ci._prevtop); + for(SQInteger i=0;i"));else scprintf(_SC(" ")); + scprintf(_SC("[%d]:"),n); + switch(type(obj)){ + case OT_FLOAT: scprintf(_SC("FLOAT %.3f"),_float(obj));break; + case OT_INTEGER: scprintf(_SC("INTEGER %d"),_integer(obj));break; + case OT_BOOL: scprintf(_SC("BOOL %s"),_integer(obj)?"true":"false");break; + case OT_STRING: scprintf(_SC("STRING %s"),_stringval(obj));break; + case OT_NULL: scprintf(_SC("NULL")); break; + case OT_TABLE: scprintf(_SC("TABLE %p[%p]"),_table(obj),_table(obj)->_delegate);break; + case OT_ARRAY: scprintf(_SC("ARRAY %p"),_array(obj));break; + case OT_CLOSURE: scprintf(_SC("CLOSURE [%p]"),_closure(obj));break; + case OT_NATIVECLOSURE: scprintf(_SC("NATIVECLOSURE"));break; + case OT_USERDATA: scprintf(_SC("USERDATA %p[%p]"),_userdataval(obj),_userdata(obj)->_delegate);break; + case OT_GENERATOR: scprintf(_SC("GENERATOR %p"),_generator(obj));break; + case OT_THREAD: scprintf(_SC("THREAD [%p]"),_thread(obj));break; + case OT_USERPOINTER: scprintf(_SC("USERPOINTER %p"),_userpointer(obj));break; + case OT_CLASS: scprintf(_SC("CLASS %p"),_class(obj));break; + case OT_INSTANCE: scprintf(_SC("INSTANCE %p"),_instance(obj));break; + case OT_WEAKREF: scprintf(_SC("WEAKERF %p"),_weakref(obj));break; + default: + assert(0); + break; + }; + scprintf(_SC("\n")); + ++n; + } +} + + + +#endif diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqvm.h b/src/modules/app_sqlang/squirrel/squirrel/sqvm.h new file mode 100644 index 00000000000..e3bb7581a1c --- /dev/null +++ b/src/modules/app_sqlang/squirrel/squirrel/sqvm.h @@ -0,0 +1,214 @@ +/* see copyright notice in squirrel.h */ +#ifndef _SQVM_H_ +#define _SQVM_H_ + +#include "sqopcodes.h" +#include "sqobject.h" +#define MAX_NATIVE_CALLS 100 +#define MIN_STACK_OVERHEAD 15 + +#define SQ_SUSPEND_FLAG -666 +#define DONT_FALL_BACK 666 +//#define EXISTS_FALL_BACK -1 + +#define GET_FLAG_RAW 0x00000001 +#define GET_FLAG_DO_NOT_RAISE_ERROR 0x00000002 +//base lib +void sq_base_register(HSQUIRRELVM 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; +}; + +#define _INLINE + +#define STK(a) _stack._vals[_stackbase+(a)] +#define TARGET _stack._vals[_stackbase+arg0] + +typedef sqvector 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; + }; + +typedef sqvector CallInfoVec; +public: + void DebugHookProxy(SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname); + static void _DebugHookProxy(HSQUIRRELVM 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,bool &suspend); + //starts a SQUIRREL 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 SQUIRREL 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 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); + + 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); +#ifdef _DEBUG_DUMP + void dumpstack(SQInteger stackbase=-1, bool dumpall = false); +#endif + +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + SQObjectType GetType() {return OT_THREAD;} +#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); } +//////////////////////////////////////////////////////////////////////////// + //stack functions for the api + void Remove(SQInteger n); + + 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); + + SQObjectPtrVec _stack; + + SQInteger _top; + SQInteger _stackbase; + SQOuter *_openouters; + SQObjectPtr _roottable; + SQObjectPtr _lasterror; + SQObjectPtr _errorhandler; + + bool _debughook; + SQDEBUGHOOK _debughook_native; + SQObjectPtr _debughook_closure; + + SQObjectPtr temp_reg; + + + CallInfo* _callsstack; + SQInteger _callsstacksize; + SQInteger _alloccallsstacksize; + sqvector _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; +}; + +struct AutoDec{ + AutoDec(SQInteger *n) { _n = n; } + ~AutoDec() { (*_n)--; } + SQInteger *_n; +}; + +inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));} + +#define _ss(_vm_) (_vm_)->_sharedstate + +#ifndef NO_GARBAGE_COLLECTOR +#define _opt_ss(_vm_) (_vm_)->_sharedstate +#else +#define _opt_ss(_vm_) NULL +#endif + +#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++; \ +} + +#define POP_CALLINFO(v){ \ + SQInteger css = --v->_callsstacksize; \ + v->ci->_closure.Null(); \ + v->ci = css?&v->_callsstack[css-1]:NULL; \ +} +#endif //_SQVM_H_ diff --git a/src/modules/app_sqlang/utils/app_sqlang_ctl b/src/modules/app_sqlang/utils/app_sqlang_ctl new file mode 100755 index 00000000000..f5a8375d4a8 --- /dev/null +++ b/src/modules/app_sqlang/utils/app_sqlang_ctl @@ -0,0 +1,143 @@ +#!/bin/bash + +# generate the .h file + +KEMI_MAX_SIZE=1024 + +cat > ../app_sqlang_kemi_export.h < +#include "../../core/kemi.h" + +#define SR_KEMI_SQLANG_EXPORT_SIZE ${KEMI_MAX_SIZE} + +typedef struct sr_kemi_sqlang_export { + SQFUNCTION pfunc; + sr_kemi_t *ket; +} sr_kemi_sqlang_export_t; + +sr_kemi_t *sr_kemi_sqlang_export_get(int idx); +SQFUNCTION sr_kemi_sqlang_export_associate(sr_kemi_t *ket); + +#endif +EOF + +# generate the .c file + +cat > ../app_sqlang_kemi_export.c < +#include +#include + +#include "../../core/dprint.h" + +#include "app_sqlang_api.h" +#include "app_sqlang_kemi_export.h" + +EOF + +CEND=${KEMI_MAX_SIZE} + +for (( c=0; c>../app_sqlang_kemi_export.c + echo "/**" >>../app_sqlang_kemi_export.c + echo " *" >>../app_sqlang_kemi_export.c + echo " */" >>../app_sqlang_kemi_export.c + echo "static SQInteger sr_kemi_sqlang_exec_func_${c}(HSQUIRRELVM J)" >>../app_sqlang_kemi_export.c + echo "{" >>../app_sqlang_kemi_export.c + echo " return sr_kemi_sqlang_exec_func(J, ${c});" >>../app_sqlang_kemi_export.c + echo "}" >>../app_sqlang_kemi_export.c +done + +echo >>../app_sqlang_kemi_export.c +echo "/**" >>../app_sqlang_kemi_export.c +echo " *" >>../app_sqlang_kemi_export.c +echo " */" >>../app_sqlang_kemi_export.c + +echo "static sr_kemi_sqlang_export_t _sr_kemi_sqlang_export_list[] = {" >>../app_sqlang_kemi_export.c +for (( c=0; c>../app_sqlang_kemi_export.c +done +echo " {NULL, NULL}" >>../app_sqlang_kemi_export.c +echo "};" >>../app_sqlang_kemi_export.c + +cat >> ../app_sqlang_kemi_export.c <=SR_KEMI_SQLANG_EXPORT_SIZE) + return NULL; + return _sr_kemi_sqlang_export_list[idx].ket; +} + +/** + * + */ +SQFUNCTION sr_kemi_sqlang_export_associate(sr_kemi_t *ket) +{ + int i; + for(i=0; i