improved and documented new stack-registration trampoline
svn: r10677
This commit is contained in:
parent
c127e5fdb7
commit
d406fb6dcf
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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: */
|
||||
|
|
Loading…
Reference in New Issue
Block a user