diff --git a/collects/scribblings/inside/memory.scrbl b/collects/scribblings/inside/memory.scrbl index 2a717c9fc8..d82b13b40d 100644 --- a/collects/scribblings/inside/memory.scrbl +++ b/collects/scribblings/inside/memory.scrbl @@ -688,7 +688,7 @@ Registers an extension's global variable that can contain Scheme @function[(int scheme_main_setup [int no_auto_statics] - [Scheme_Main main] + [Scheme_Env_Main main] [int argc] [char** argv])]{ @@ -697,11 +697,11 @@ calling @cpp{scheme_basic_env}, and then calls @var{main} with the namespace, @var{argc}, and @var{argv}. (The @var{argc} and @var{argv} are just passed on to @var{main}, and are not inspected in any way.) -The @cpp{Scheme_Main} type is defined as follows: +The @cpp{Scheme_Env_Main} type is defined as follows: @verbatim[#:indent 4]{ -typedef int (*Scheme_Main)(Scheme_Env *env, - int argc, char **argv); +typedef int (*Scheme_Env_Main)(Scheme_Env *env, + int argc, char **argv); } The result of @var{main} is the result of @cpp{scheme_main_setup}. @@ -711,6 +711,24 @@ explicitly registered with the garbage collector; see @secref["im:memoryalloc"] for more information.} +@function[(int scheme_main_stack_setup + [int no_auto_statics] + [Scheme_Nested_Main main] + [void* data])]{ + +A more primitive variant of @cpp{scheme_main_setup} that initializes +the GC stack base but does not create the initial namespace (so an +embedding application can perform other operations that involve +garbage-collected data before creating a namespace). + +The @var{data} argument is passed through to @var{main}, where the +@cpp{Scheme_Nested_Main} type is defined as follows: + +@verbatim[#:indent 4]{ +typedef int (*Scheme_Nested_Main)(void *data); +}} + + @function[(void scheme_set_stack_base [void* stack_addr] [int no_auto_statics])]{ @@ -739,7 +757,7 @@ must be the beginning or end of a local-frame registration. Worse, in CGC or 3m, if @cpp{real_main} is declared @cpp{static}, the compiler may inline it and place variables containing collectable values deeper in the stack than @cpp{dummy}. To avoid these problems, use -@cpp{scheme_main_setup}, instead.} +@cpp{scheme_main_setup} or @cpp{scheme_main_stack_setup}, instead.} @function[(void scheme_set_stack_bounds [void* stack_addr] diff --git a/collects/scribblings/inside/overview.scrbl b/collects/scribblings/inside/overview.scrbl index 9227183e1a..5b193fd234 100644 --- a/collects/scribblings/inside/overview.scrbl +++ b/collects/scribblings/inside/overview.scrbl @@ -296,13 +296,16 @@ To embed PLT Scheme CGC in a program, follow these steps: installing from source also places this file in the installation's @filepath{include} directory.} - @item{Start your main program through the @cpp{scheme_main_setup} - trampoline, and put all uses of MzScheme functions inside the - function passed to @cpp{scheme_main_setup}. The @cpp{scheme_main_setup} - function registers the current C stack location with the memory - manager. It also creates the initial namespace @cpp{Scheme_Env*} by - calling @cppi{scheme_basic_env} and passing the result to the - function provided to @cpp{scheme_main_setup}.} + @item{Start your main program through the @cpp{scheme_main_setup} (or + @cpp{scheme_main_stack_setup}) trampoline, and put all uses of + MzScheme functions inside the function passed to + @cpp{scheme_main_setup}. The @cpp{scheme_main_setup} function + registers the current C stack location with the memory manager. It + also creates the initial namespace @cpp{Scheme_Env*} by calling + @cppi{scheme_basic_env} and passing the result to the function + provided to @cpp{scheme_main_setup}. (The + @cpp{scheme_main_stack_setup} trampoline registers the C stack with + the memory manager without creating a namespace.)} @item{Configure the namespace by adding module declarations. The initial namespace contains declarations only for a few primitive diff --git a/src/mred/mrmain.cxx b/src/mred/mrmain.cxx index 270b75476d..883af50381 100644 --- a/src/mred/mrmain.cxx +++ b/src/mred/mrmain.cxx @@ -252,7 +252,7 @@ int actual_main(int argc, char **argv) return r; } -static int main_after_stack(void *data, int argc, char *argv[]) +static int main_after_stack(int argc, char *argv[]) { int rval; @@ -299,9 +299,24 @@ static int main_after_stack(void *data, int argc, char *argv[]) /* Just jumps to generic main. */ #ifndef wx_msw + +typedef struct { + int argc; + char **argv; +} Main_Args; + +static int call_main_after_stack(void *data) +{ + Main_Args *ma = (Main_Args *)data; + return main_after_stack(ma->argc, ma->argv); +} + int main(int argc, char *argv[]) { - return scheme_main_stack_setup(1, main_after_stack, NULL, argc, argv); + Main_Args ma; + ma.argc = argc; + ma.argv = argv; + return scheme_main_stack_setup(1, call_main_after_stack, &ma); } #endif @@ -517,22 +532,19 @@ typedef struct { int wm_is_mred; HINSTANCE hInstance; HINSTANCE hPrevInstance; + int argc; + char **argv; int nCmdShow; } WinMain_Args; -static int call_main_after_stack(int argc, char *argv[]) -{ - return main_after_stack(NULL, argc, argv); -} - -static int WinMain_after_stack(void *_wma, int argc, char **argv) +static int WinMain_after_stack(void *_wma) { WinMain_Args *wma = (WinMain_Args *)_wma; return wxWinMain(wma->wm_is_mred, wma->hInstance, wma->hPrevInstance, - argc, argv, + wma->argc, wma->argv, wma->nCmdShow, - call_main_after_stack); + main_after_stack); } int APIENTRY WinMain_dlls_ready(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR ignored, int nCmdShow) @@ -628,9 +640,11 @@ int APIENTRY WinMain_dlls_ready(HINSTANCE hInstance, HINSTANCE hPrevInstance, LP wma.wm_is_mred = wm_is_mred; wma.hInstance = hInstance; wma.hPrevInstance = hPrevInstance; + wma.argc = argc; + wma.argv = argv; wma.nCmdShow = nCmdShow; - return scheme_main_stack_setup(1, WinMain_after_stack, &wma, argc, argv); + return scheme_main_stack_setup(1, WinMain_after_stack, &wma); } # ifdef MZ_PRECISE_GC diff --git a/src/mzscheme/include/scheme.h b/src/mzscheme/include/scheme.h index 6e3560ab1b..b09e9b42bc 100644 --- a/src/mzscheme/include/scheme.h +++ b/src/mzscheme/include/scheme.h @@ -1697,12 +1697,12 @@ MZ_EXTERN void scheme_set_stack_base(void *base, int no_auto_statics); MZ_EXTERN void scheme_set_stack_bounds(void *base, void *deepest, int no_auto_statics); /* Stack-preparation start-up: */ -typedef int (*Scheme_Startup_Main)(void *data, int argc, char **argv); -MZ_EXTERN int scheme_main_stack_setup(int no_auto_statics, Scheme_Startup_Main _main, void *data, int argc, char **argv); +typedef int (*Scheme_Nested_Main)(void *data); +MZ_EXTERN int scheme_main_stack_setup(int no_auto_statics, Scheme_Nested_Main _main, void *data); /* More automatic start-up: */ -typedef int (*Scheme_Main)(Scheme_Env *env, int argc, char **argv); -MZ_EXTERN int scheme_main_setup(int no_auto_statics, Scheme_Main _main, int argc, char **argv); +typedef int (*Scheme_Env_Main)(Scheme_Env *env, int argc, char **argv); +MZ_EXTERN int scheme_main_setup(int no_auto_statics, Scheme_Env_Main _main, int argc, char **argv); MZ_EXTERN void scheme_register_static(void *ptr, long size); diff --git a/src/mzscheme/main.c b/src/mzscheme/main.c index 26f4fc6957..ffd557edf1 100644 --- a/src/mzscheme/main.c +++ b/src/mzscheme/main.c @@ -213,7 +213,7 @@ int actual_main(int argc, char *argv[]); /* Prepare for delayload, then call main_after_dlls */ static int main_after_dlls(int argc, MAIN_char **MAIN_argv); -static int main_after_stack(void *data, int argc, MAIN_char **MAIN_argv); +static int main_after_stack(void *data); # ifdef MZ_PRECISE_GC START_XFORM_SKIP; @@ -240,23 +240,34 @@ END_XFORM_SKIP; /************************ main_after_dlls **************************/ /* Prep stack for GC, then call main_after_stack (indirectly) */ +typedef struct { + int argc; + MAIN_char **argv; +} Main_Args; + static int main_after_dlls(int argc, MAIN_char **argv) { - return scheme_main_stack_setup(1, - (Scheme_Startup_Main)main_after_stack, NULL, - argc, (char **)argv); + Main_Args ma; + ma.argc = argc; + ma.argv = argv; + return scheme_main_stack_setup(1, main_after_stack, &ma); } /************************ main_after_stack *************************/ /* Phase 1 setup, then call actual_main (indirectly) */ -static int main_after_stack(void *data, int argc, MAIN_char **MAIN_argv) +static int main_after_stack(void *data) { int rval; + int argc; + MAIN_char **MAIN_argv; #ifdef WINDOWS_UNICODE_MAIN char **argv; #endif + argc = ((Main_Args *)data)->argc; + MAIN_argv = ((Main_Args *)data)->argv; + #if defined(OSKIT) && !defined(OSKIT_TEST) && !KNIT oskit_prepare(&argc, &argv); #endif diff --git a/src/mzscheme/src/salloc.c b/src/mzscheme/src/salloc.c index c8c57a74be..f37c377d17 100644 --- a/src/mzscheme/src/salloc.c +++ b/src/mzscheme/src/salloc.c @@ -89,30 +89,36 @@ void scheme_set_stack_base(void *base, int no_auto_statics) } typedef struct { - Scheme_Main _main; + Scheme_Env_Main _main; + int argc; + char **argv; } Scheme_Main_Data; -static int call_with_basic(void *data, int argc, char **argv) +static int call_with_basic(void *data) { - Scheme_Main _main = ((Scheme_Main_Data *)data)->_main; - return _main(scheme_basic_env(), argc, argv); + Scheme_Main_Data *ma = (Scheme_Main_Data *)data; + Scheme_Env_Main _main = ma->_main; + + return _main(scheme_basic_env(), ma->argc, ma->argv); } -int scheme_main_setup(int no_auto_statics, Scheme_Main _main, int argc, char **argv) +int scheme_main_setup(int no_auto_statics, Scheme_Env_Main _main, int argc, char **argv) { Scheme_Main_Data d; d._main = _main; - return scheme_main_stack_setup(no_auto_statics, call_with_basic, &d, argc, argv); + d.argc = argc; + d.argv = argv; + return scheme_main_stack_setup(no_auto_statics, call_with_basic, &d); } -int scheme_main_stack_setup(int no_auto_statics, Scheme_Startup_Main _main, void *data, int argc, char **argv) +int scheme_main_stack_setup(int no_auto_statics, Scheme_Nested_Main _main, void *data) { void *stack_start; int volatile return_code; scheme_set_stack_base(PROMPT_STACK(stack_start), no_auto_statics); - return_code = _main(data, argc, argv); + return_code = _main(data); #ifdef MZ_PRECISE_GC /* Trick xform conversion to keep start_addr: */