|
|
@@ -8,98 +8,119 @@
|
|
|
#include <stdio.h>
|
|
|
|
|
|
#include "squirrel.h"
|
|
|
-#include <sqstdblob.h>
|
|
|
-#include <sqstdsystem.h>
|
|
|
-#include <sqstdio.h>
|
|
|
-#include <sqstdmath.h>
|
|
|
+#include <sqstdblob.h>
|
|
|
+#include <sqstdsystem.h>
|
|
|
+#include <sqstdio.h>
|
|
|
+#include <sqstdmath.h>
|
|
|
#include <sqstdstring.h>
|
|
|
|
|
|
-/*
|
|
|
-** Copies values from State src to State dst.
|
|
|
-*/
|
|
|
-static SQRESULT copy_values_between_vms (HSQUIRRELVM dst, HSQUIRRELVM src, int argc, int argIdx) {
|
|
|
- SQRESULT _rc_;
|
|
|
- sq_reservestack(dst, argc + 20);
|
|
|
- argc += argIdx; //we will work with argc args starting at argIdx
|
|
|
- for (; argIdx < argc; argIdx++) {
|
|
|
- switch (sq_gettype(src, argIdx)) {
|
|
|
- case OT_INTEGER:
|
|
|
- SQ_GET_INTEGER(src, argIdx, vint);
|
|
|
- sq_pushinteger(dst, vint);
|
|
|
- break;
|
|
|
- case OT_FLOAT:
|
|
|
- SQ_GET_FLOAT(src, argIdx, vfloat);
|
|
|
- sq_pushfloat (dst, vfloat);
|
|
|
- break;
|
|
|
- case OT_BOOL:
|
|
|
- SQ_GET_BOOL(src, argIdx, vbool);
|
|
|
- sq_pushbool (dst, vbool);
|
|
|
- break;
|
|
|
- case OT_STRING: {
|
|
|
- SQ_GET_STRING(src, argIdx, vstr)
|
|
|
- sq_pushstring (dst, vstr, vstr_size);
|
|
|
- break;
|
|
|
- }
|
|
|
- case OT_ARRAY:{
|
|
|
- SQInteger size = sq_getsize(src, argIdx);
|
|
|
- sq_newarray(dst, size);
|
|
|
- for(SQInteger i=0; i<size; ++i){
|
|
|
+/*
|
|
|
+** Copies values from State src to State dst.
|
|
|
+*/
|
|
|
+static SQRESULT copy_values_between_vms (HSQUIRRELVM dst, HSQUIRRELVM src, int argc, int argIdx)
|
|
|
+{
|
|
|
+ SQRESULT _rc_;
|
|
|
+ sq_reservestack(dst, argc + 20);
|
|
|
+ argc += argIdx; //we will work with argc args starting at argIdx
|
|
|
+ for (; argIdx < argc; argIdx++)
|
|
|
+ {
|
|
|
+ switch (sq_gettype(src, argIdx))
|
|
|
+ {
|
|
|
+ case OT_INTEGER:
|
|
|
+ SQ_GET_INTEGER(src, argIdx, vint);
|
|
|
+ sq_pushinteger(dst, vint);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OT_FLOAT:
|
|
|
+ SQ_GET_FLOAT(src, argIdx, vfloat);
|
|
|
+ sq_pushfloat (dst, vfloat);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OT_BOOL:
|
|
|
+ SQ_GET_BOOL(src, argIdx, vbool);
|
|
|
+ sq_pushbool (dst, vbool);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OT_STRING:
|
|
|
+ {
|
|
|
+ SQ_GET_STRING(src, argIdx, vstr)
|
|
|
+ sq_pushstring (dst, vstr, vstr_size);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OT_ARRAY:
|
|
|
+ {
|
|
|
+ SQInteger size = sq_getsize(src, argIdx);
|
|
|
+ sq_newarray(dst, size);
|
|
|
+ for(SQInteger i=0; i<size; ++i)
|
|
|
+ {
|
|
|
sq_pushinteger(src, i);
|
|
|
sq_get(src, -2);
|
|
|
sq_pushinteger(dst, i);
|
|
|
if(copy_values_between_vms(dst, src, 1, sq_gettop(src)) != SQ_OK) return SQ_ERROR;
|
|
|
sq_poptop(src);
|
|
|
sq_set(dst, -3);
|
|
|
- }
|
|
|
- }
|
|
|
- break;
|
|
|
- case OT_TABLE:{
|
|
|
- sq_newtable(dst);
|
|
|
- sq_pushnull(src);
|
|
|
- while(sq_next(src, -2) == SQ_OK){
|
|
|
- SQInteger src_top = sq_gettop(src);
|
|
|
- if(copy_values_between_vms(dst, src, 1, src_top-1) != SQ_OK
|
|
|
- || copy_values_between_vms(dst, src, 1, src_top) != SQ_OK) return SQ_ERROR;
|
|
|
- sq_newslot(dst, -3, SQFalse);
|
|
|
- sq_pop(src, 2);
|
|
|
- }
|
|
|
- }
|
|
|
- break;
|
|
|
- case OT_USERPOINTER: {
|
|
|
- SQUserPointer ptr;
|
|
|
- sq_getuserpointer(src, argIdx, &ptr);
|
|
|
- sq_pushuserpointer(dst, ptr);
|
|
|
- break;
|
|
|
- }
|
|
|
- case OT_NULL:
|
|
|
- sq_pushnull(dst);
|
|
|
- break;
|
|
|
- default:
|
|
|
- return SQ_ERROR;
|
|
|
- }
|
|
|
- }
|
|
|
- return SQ_OK;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OT_TABLE:
|
|
|
+ {
|
|
|
+ sq_newtable(dst);
|
|
|
+ sq_pushnull(src);
|
|
|
+ while(sq_next(src, -2) == SQ_OK)
|
|
|
+ {
|
|
|
+ SQInteger src_top = sq_gettop(src);
|
|
|
+ if(copy_values_between_vms(dst, src, 1, src_top-1) != SQ_OK
|
|
|
+ || copy_values_between_vms(dst, src, 1, src_top) != SQ_OK) return SQ_ERROR;
|
|
|
+ sq_newslot(dst, -3, SQFalse);
|
|
|
+ sq_pop(src, 2);
|
|
|
+ }
|
|
|
+ sq_pop(src,1);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OT_USERPOINTER:
|
|
|
+ {
|
|
|
+ SQUserPointer ptr;
|
|
|
+ sq_getuserpointer(src, argIdx, &ptr);
|
|
|
+ sq_pushuserpointer(dst, ptr);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case OT_NULL:
|
|
|
+ sq_pushnull(dst);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ return SQ_ERROR;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return SQ_OK;
|
|
|
}
|
|
|
|
|
|
|
|
|
static const SQChar sq_slave_vm_TAG[] = _SC("SlaveVM");
|
|
|
|
|
|
-static SQRESULT get_slave_vm_instance(HSQUIRRELVM v, SQInteger idx, HSQUIRRELVM *vm) {
|
|
|
- if(sq_getinstanceup(v, idx, (SQUserPointer*)vm, (void*)sq_slave_vm_TAG) != SQ_OK) return SQ_ERROR;
|
|
|
- if(!vm) return sq_throwerror(v, _SC("slave vm already closed"));
|
|
|
- return SQ_OK;
|
|
|
+static SQRESULT get_slave_vm_instance(HSQUIRRELVM v, SQInteger idx, HSQUIRRELVM *vm)
|
|
|
+{
|
|
|
+ if(sq_getinstanceup(v, idx, (SQUserPointer*)vm, (void*)sq_slave_vm_TAG) != SQ_OK) return SQ_ERROR;
|
|
|
+ if(!vm) return sq_throwerror(v, _SC("slave vm already closed"));
|
|
|
+ return SQ_OK;
|
|
|
}
|
|
|
|
|
|
#define GET_sq_slave_vm_INSTANCE(v, idx) \
|
|
|
HSQUIRRELVM self=NULL; if(get_slave_vm_instance(v, idx, &self) != SQ_OK) return SQ_ERROR;
|
|
|
|
|
|
-static SQRESULT sq_slave_vm__tostring (HSQUIRRELVM v) {
|
|
|
+static SQRESULT sq_slave_vm__tostring (HSQUIRRELVM v)
|
|
|
+{
|
|
|
GET_sq_slave_vm_INSTANCE(v, 1);
|
|
|
sq_pushfstring (v, _SC("Squirrel vm (%p)"), self);
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
-static SQRESULT sq_slave_vm_release_hook(SQUserPointer p, SQInteger size, HSQUIRRELVM v) {
|
|
|
+static SQRESULT sq_slave_vm_release_hook(SQUserPointer p, SQInteger size, HSQUIRRELVM v)
|
|
|
+{
|
|
|
HSQUIRRELVM self = (HSQUIRRELVM)p;
|
|
|
if(self) sq_close(self);
|
|
|
return 0;
|
|
|
@@ -108,7 +129,8 @@ static SQRESULT sq_slave_vm_release_hook(SQUserPointer p, SQInteger size, HSQUIR
|
|
|
/*
|
|
|
** Creates a new SQuirrel vm.
|
|
|
*/
|
|
|
-static SQRESULT sq_slave_vm_constructor (HSQUIRRELVM v) {
|
|
|
+static SQRESULT sq_slave_vm_constructor (HSQUIRRELVM v)
|
|
|
+{
|
|
|
SQ_FUNC_VARS(v);
|
|
|
SQ_OPT_INTEGER(v, 2, stack_size, 1024);
|
|
|
HSQUIRRELVM self = sq_open(stack_size);
|
|
|
@@ -117,57 +139,65 @@ static SQRESULT sq_slave_vm_constructor (HSQUIRRELVM v) {
|
|
|
sq_setprintfunc(self,sq_getprintfunc(v),sq_geterrorfunc(v));
|
|
|
|
|
|
/* load base libraries */
|
|
|
- sq_pushroottable(self);
|
|
|
-
|
|
|
- sqstd_register_bloblib(self);
|
|
|
- sqstd_register_iolib(self);
|
|
|
- sqstd_register_systemlib(self);
|
|
|
- sqstd_register_mathlib(self);
|
|
|
- sqstd_register_stringlib(self);
|
|
|
- sq_poptop(self); //remove root table
|
|
|
-
|
|
|
- sq_setinstanceup(v, 1, self);
|
|
|
- sq_setreleasehook(v, 1, sq_slave_vm_release_hook);
|
|
|
-
|
|
|
- return 1;
|
|
|
+ sq_pushroottable(self);
|
|
|
+
|
|
|
+ sqstd_register_bloblib(self);
|
|
|
+ sqstd_register_iolib(self);
|
|
|
+ sqstd_register_systemlib(self);
|
|
|
+ sqstd_register_mathlib(self);
|
|
|
+ sqstd_register_stringlib(self);
|
|
|
+ sq_poptop(self); //remove root table
|
|
|
+
|
|
|
+ sq_setinstanceup(v, 1, self);
|
|
|
+ sq_setreleasehook(v, 1, sq_slave_vm_release_hook);
|
|
|
+
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
-static SQRESULT sq_slave_vm_close(HSQUIRRELVM v){
|
|
|
- GET_sq_slave_vm_INSTANCE(v, 1);
|
|
|
- sq_close(self);
|
|
|
+static SQRESULT sq_slave_vm_close(HSQUIRRELVM v)
|
|
|
+{
|
|
|
+ GET_sq_slave_vm_INSTANCE(v, 1);
|
|
|
+ sq_close(self);
|
|
|
sq_setinstanceup(v, 1, 0); //next calls will fail with "vm is closed"
|
|
|
- return 0;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
-static SQRESULT sq_slave_vm_call(HSQUIRRELVM v){
|
|
|
+static SQRESULT sq_slave_vm_call(HSQUIRRELVM v)
|
|
|
+{
|
|
|
SQ_FUNC_VARS_NO_TOP(v);
|
|
|
- GET_sq_slave_vm_INSTANCE(v, 1);
|
|
|
- SQ_GET_BOOL(v, 2, has_ret_val);
|
|
|
- SQ_GET_STRING(v, 3, func_name);
|
|
|
+ GET_sq_slave_vm_INSTANCE(v, 1);
|
|
|
+ SQ_GET_BOOL(v, 2, has_ret_val);
|
|
|
+ SQ_GET_STRING(v, 3, func_name);
|
|
|
SQInteger top = sq_gettop(self);
|
|
|
SQRESULT result = SQ_ERROR;
|
|
|
sq_pushroottable(self);
|
|
|
sq_pushstring(self, func_name, func_name_size);
|
|
|
- if(sq_get(self, -2) == SQ_OK){
|
|
|
- switch(sq_gettype(self, -1)){
|
|
|
- case OT_CLOSURE:
|
|
|
- case OT_NATIVECLOSURE:
|
|
|
- case OT_CLASS:{
|
|
|
- sq_pushroottable(self);
|
|
|
- int argc = sq_gettop(v) - 3;
|
|
|
- if(argc && copy_values_between_vms(self, v, argc, 4) != SQ_OK) {
|
|
|
- sq_throwerror(v, sq_getlasterror_str(self));
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
- if(sq_call(self, argc+1, has_ret_val, SQFalse) != SQ_OK){
|
|
|
- sq_throwerror(v, sq_getlasterror_str(self));
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
- if(has_ret_val){
|
|
|
- if(copy_values_between_vms(v, self, 1, sq_gettop(self)) == SQ_OK) result = 1;
|
|
|
- }
|
|
|
- else result = SQ_OK;
|
|
|
+ if(sq_get(self, -2) == SQ_OK)
|
|
|
+ {
|
|
|
+ switch(sq_gettype(self, -1))
|
|
|
+ {
|
|
|
+ case OT_CLOSURE:
|
|
|
+ case OT_NATIVECLOSURE:
|
|
|
+ case OT_CLASS:
|
|
|
+ {
|
|
|
+ sq_pushroottable(self);
|
|
|
+ int argc = sq_gettop(v) - 3;
|
|
|
+ if(argc && copy_values_between_vms(self, v, argc, 4) != SQ_OK)
|
|
|
+ {
|
|
|
+ sq_throwerror(v, sq_getlasterror_str(self));
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+ if(sq_call(self, argc+1, has_ret_val, SQFalse) != SQ_OK)
|
|
|
+ {
|
|
|
+ sq_throwerror(v, sq_getlasterror_str(self));
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+ if(has_ret_val)
|
|
|
+ {
|
|
|
+ if(copy_values_between_vms(v, self, 1, sq_gettop(self)) == SQ_OK) result = 1;
|
|
|
}
|
|
|
+ else result = SQ_OK;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
@@ -176,33 +206,38 @@ static SQRESULT sq_slave_vm_call(HSQUIRRELVM v){
|
|
|
}
|
|
|
cleanup:
|
|
|
sq_settop(self, top);
|
|
|
- return result;
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
-static SQRESULT sq_slave_vm_set(HSQUIRRELVM v){
|
|
|
- GET_sq_slave_vm_INSTANCE(v, 1);
|
|
|
+static SQRESULT sq_slave_vm_set(HSQUIRRELVM v)
|
|
|
+{
|
|
|
+ GET_sq_slave_vm_INSTANCE(v, 1);
|
|
|
SQInteger top = sq_gettop(self);
|
|
|
SQRESULT result;
|
|
|
sq_pushroottable(self);
|
|
|
if(copy_values_between_vms(self, v, 1, 2) == SQ_OK
|
|
|
- && copy_values_between_vms(self, v, 1, 3) == SQ_OK) {
|
|
|
+ && copy_values_between_vms(self, v, 1, 3) == SQ_OK)
|
|
|
+ {
|
|
|
result = sq_newslot(self, -3, SQFalse);
|
|
|
if(result == SQ_ERROR) sq_throwerror(v, sq_getlasterror_str(self));
|
|
|
}
|
|
|
else result = SQ_ERROR;
|
|
|
sq_settop(self, top);
|
|
|
- return result;
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
-static SQRESULT sq_slave_vm_get(HSQUIRRELVM v){
|
|
|
- GET_sq_slave_vm_INSTANCE(v, 1);
|
|
|
+static SQRESULT sq_slave_vm_get(HSQUIRRELVM v)
|
|
|
+{
|
|
|
+ GET_sq_slave_vm_INSTANCE(v, 1);
|
|
|
SQInteger top = sq_gettop(self);
|
|
|
SQRESULT result = SQ_ERROR;
|
|
|
sq_pushroottable(self);
|
|
|
- if(copy_values_between_vms(self, v, 1, 2) == SQ_OK) {
|
|
|
+ if(copy_values_between_vms(self, v, 1, 2) == SQ_OK)
|
|
|
+ {
|
|
|
if(sq_get(self, -2) == SQ_OK
|
|
|
- && copy_values_between_vms(v, self, 1, sq_gettop(self)) == SQ_OK){
|
|
|
- result = 1;
|
|
|
+ && copy_values_between_vms(v, self, 1, sq_gettop(self)) == SQ_OK)
|
|
|
+ {
|
|
|
+ result = 1;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
@@ -211,64 +246,71 @@ static SQRESULT sq_slave_vm_get(HSQUIRRELVM v){
|
|
|
}
|
|
|
}
|
|
|
sq_settop(self, top);
|
|
|
- return result;
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
-static SQRESULT sq_slave_vm_dofile(HSQUIRRELVM v){
|
|
|
+static SQRESULT sq_slave_vm_dofile(HSQUIRRELVM v)
|
|
|
+{
|
|
|
SQ_FUNC_VARS(v);
|
|
|
- GET_sq_slave_vm_INSTANCE(v, 1);
|
|
|
+ GET_sq_slave_vm_INSTANCE(v, 1);
|
|
|
SQ_GET_STRING(v, 2, file_name);
|
|
|
SQ_OPT_BOOL(v, 3, retval, false);
|
|
|
SQ_OPT_BOOL(v, 4, printerror, false);
|
|
|
SQ_OPT_BOOL(v, 5, show_warnings, false);
|
|
|
- SQInteger top = sq_gettop(self);
|
|
|
+ SQInteger top = sq_gettop(self);
|
|
|
SQRESULT result = SQ_ERROR;
|
|
|
sq_pushroottable(self); //important always push the root table, because sqstd_dofile will try to do a sq_push(v, -2)
|
|
|
- if(sqstd_dofile(self, file_name, retval, printerror, show_warnings) >= 0){
|
|
|
- if(retval){
|
|
|
+ if(sqstd_dofile(self, file_name, retval, printerror, show_warnings) >= 0)
|
|
|
+ {
|
|
|
+ if(retval)
|
|
|
+ {
|
|
|
if(copy_values_between_vms(v, self, 1, sq_gettop(self)) == SQ_OK) result = 1;
|
|
|
}
|
|
|
else result = SQ_OK;
|
|
|
}
|
|
|
else sq_throwerror(v, sq_getlasterror_str(self));
|
|
|
sq_settop(self, top);
|
|
|
- return result;
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
-static SQRESULT sq_slave_vm_loadfile(HSQUIRRELVM v){
|
|
|
+static SQRESULT sq_slave_vm_loadfile(HSQUIRRELVM v)
|
|
|
+{
|
|
|
SQ_FUNC_VARS(v);
|
|
|
- GET_sq_slave_vm_INSTANCE(v, 1);
|
|
|
+ GET_sq_slave_vm_INSTANCE(v, 1);
|
|
|
SQ_GET_STRING(v, 2, func_name);
|
|
|
SQ_GET_STRING(v, 3, file_name);
|
|
|
SQ_OPT_BOOL(v, 4, printerror, false);
|
|
|
SQ_OPT_BOOL(v, 5, show_warnings, false);
|
|
|
- SQInteger top = sq_gettop(self);
|
|
|
+ SQInteger top = sq_gettop(self);
|
|
|
SQRESULT result = SQ_ERROR;
|
|
|
sq_pushroottable(self);
|
|
|
sq_pushstring(self, func_name, func_name_size);
|
|
|
- if(sqstd_loadfile(self, file_name, printerror, show_warnings) >= 0){
|
|
|
+ if(sqstd_loadfile(self, file_name, printerror, show_warnings) >= 0)
|
|
|
+ {
|
|
|
result = sq_newslot(self, -3, SQFalse);
|
|
|
}
|
|
|
sq_settop(self, top);
|
|
|
- return result;
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
-static SQRESULT sq_slave_vm_compilestring(HSQUIRRELVM v){
|
|
|
+static SQRESULT sq_slave_vm_compilestring(HSQUIRRELVM v)
|
|
|
+{
|
|
|
SQ_FUNC_VARS(v);
|
|
|
- GET_sq_slave_vm_INSTANCE(v, 1);
|
|
|
+ GET_sq_slave_vm_INSTANCE(v, 1);
|
|
|
SQ_GET_STRING(v, 2, func_name);
|
|
|
SQ_GET_STRING(v, 3, str_script);
|
|
|
SQ_OPT_BOOL(v, 4, printerror, false);
|
|
|
SQ_OPT_BOOL(v, 5, show_warnings, false);
|
|
|
- SQInteger top = sq_gettop(self);
|
|
|
+ SQInteger top = sq_gettop(self);
|
|
|
SQRESULT result = SQ_ERROR;
|
|
|
sq_pushroottable(self);
|
|
|
sq_pushstring(self, func_name, func_name_size);
|
|
|
- if(sq_compilebuffer(self, str_script, str_script_size, func_name, printerror, show_warnings) >= 0){
|
|
|
+ if(sq_compilebuffer(self, str_script, str_script_size, func_name, printerror, show_warnings) >= 0)
|
|
|
+ {
|
|
|
result = sq_newslot(self, -3, SQFalse);
|
|
|
}
|
|
|
sq_settop(self, top);
|
|
|
- return result;
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
#ifdef __cplusplus
|