diff --git a/src/mzscheme/cmdline.inc b/src/mzscheme/cmdline.inc index c92002c3f7..a8036a941f 100644 --- a/src/mzscheme/cmdline.inc +++ b/src/mzscheme/cmdline.inc @@ -906,6 +906,7 @@ static int run_from_cmd_line(int argc, char *_argv[], break; case '-': no_more_switches = 1; + was_config_flag = 1; break; case 'j': scheme_set_startup_use_jit(0); diff --git a/src/mzscheme/include/mzscheme.exp b/src/mzscheme/include/mzscheme.exp index 2a42cfd036..3d818ebd4d 100644 --- a/src/mzscheme/include/mzscheme.exp +++ b/src/mzscheme/include/mzscheme.exp @@ -205,6 +205,7 @@ scheme_make_prim scheme_make_noneternal_prim scheme_make_prim_w_arity scheme_make_folding_prim +scheme_make_immed_prim scheme_make_noncm_prim scheme_make_noneternal_prim_w_arity scheme_make_prim_w_everything diff --git a/src/mzscheme/include/mzscheme3m.exp b/src/mzscheme/include/mzscheme3m.exp index 15bf60e8e9..0e765ddf95 100644 --- a/src/mzscheme/include/mzscheme3m.exp +++ b/src/mzscheme/include/mzscheme3m.exp @@ -215,6 +215,7 @@ scheme_make_prim scheme_make_noneternal_prim scheme_make_prim_w_arity scheme_make_folding_prim +scheme_make_immed_prim scheme_make_noncm_prim scheme_make_noneternal_prim_w_arity scheme_make_prim_w_everything diff --git a/src/mzscheme/include/mzwin.def b/src/mzscheme/include/mzwin.def index c95a780f6e..4e9c41cd81 100644 --- a/src/mzscheme/include/mzwin.def +++ b/src/mzscheme/include/mzwin.def @@ -193,6 +193,7 @@ EXPORTS scheme_make_noneternal_prim scheme_make_prim_w_arity scheme_make_folding_prim + scheme_make_immed_prim scheme_make_noncm_prim scheme_make_noneternal_prim_w_arity scheme_make_prim_w_everything diff --git a/src/mzscheme/include/mzwin3m.def b/src/mzscheme/include/mzwin3m.def index 1ec30af225..80d06b7a94 100644 --- a/src/mzscheme/include/mzwin3m.def +++ b/src/mzscheme/include/mzwin3m.def @@ -207,6 +207,7 @@ EXPORTS scheme_make_noneternal_prim scheme_make_prim_w_arity scheme_make_folding_prim + scheme_make_immed_prim scheme_make_noncm_prim scheme_make_noneternal_prim_w_arity scheme_make_prim_w_everything diff --git a/src/mzscheme/include/scheme.h b/src/mzscheme/include/scheme.h index 52aa7becdf..b0758ce03c 100644 --- a/src/mzscheme/include/scheme.h +++ b/src/mzscheme/include/scheme.h @@ -612,26 +612,31 @@ typedef struct Scheme_Offset_Cptr /* Constants for flags in Scheme_Primitive_[Closed]_Proc. Do not use them directly. */ -#define SCHEME_PRIM_IS_FOLDING 1 -#define SCHEME_PRIM_IS_PRIMITIVE 2 -#define SCHEME_PRIM_IS_STRUCT_INDEXED_GETTER 4 -#define SCHEME_PRIM_IS_STRUCT_PRED 8 -#define SCHEME_PRIM_IS_PARAMETER 16 -#define SCHEME_PRIM_IS_STRUCT_OTHER 32 -#define SCHEME_PRIM_STRUCT_OTHER_TYPE_MASK (64 | 128) -#define SCHEME_PRIM_IS_MULTI_RESULT 256 -#define SCHEME_PRIM_IS_BINARY_INLINED 512 -#define SCHEME_PRIM_IS_USER_PARAMETER 1024 -#define SCHEME_PRIM_IS_METHOD 2048 -#define SCHEME_PRIM_IS_CLOSURE 4096 -#define SCHEME_PRIM_IS_NONCM 8192 +#define SCHEME_PRIM_OPT_MASK (1 | 2) +#define SCHEME_PRIM_IS_PRIMITIVE 4 +#define SCHEME_PRIM_IS_STRUCT_INDEXED_GETTER 8 +#define SCHEME_PRIM_IS_STRUCT_PRED 16 +#define SCHEME_PRIM_IS_PARAMETER 32 +#define SCHEME_PRIM_IS_STRUCT_OTHER 64 +#define SCHEME_PRIM_STRUCT_OTHER_TYPE_MASK (128 | 256) +#define SCHEME_PRIM_IS_MULTI_RESULT 512 +#define SCHEME_PRIM_IS_BINARY_INLINED 1024 +#define SCHEME_PRIM_IS_USER_PARAMETER 2048 +#define SCHEME_PRIM_IS_METHOD 4096 +#define SCHEME_PRIM_IS_CLOSURE 8192 #define SCHEME_PRIM_IS_UNARY_INLINED 16384 #define SCHEME_PRIM_IS_MIN_NARY_INLINED 32768 +/* Values with SCHEME_PRIM_OPT_MASK, earlier implies later: */ +#define SCHEME_PRIM_OPT_FOLDING 3 +#define SCHEME_PRIM_OPT_IMMEDIATE 2 +#define SCHEME_PRIM_OPT_NONCM 1 + +/* Values with SCHEME_PRIM_STRUCT_OTHER_TYPE_MASK */ #define SCHEME_PRIM_STRUCT_TYPE_INDEXLESS_GETTER 0 -#define SCHEME_PRIM_STRUCT_TYPE_CONSTR 64 -#define SCHEME_PRIM_STRUCT_TYPE_INDEXLESS_SETTER 128 -#define SCHEME_PRIM_STRUCT_TYPE_INDEXED_SETTER (64 | 128) +#define SCHEME_PRIM_STRUCT_TYPE_CONSTR 128 +#define SCHEME_PRIM_STRUCT_TYPE_INDEXLESS_SETTER 256 +#define SCHEME_PRIM_STRUCT_TYPE_INDEXED_SETTER (128 | 256) #define SCHEME_PRIM_IS_STRUCT_PROC (SCHEME_PRIM_IS_STRUCT_INDEXED_GETTER | SCHEME_PRIM_IS_STRUCT_PRED | SCHEME_PRIM_IS_STRUCT_OTHER) diff --git a/src/mzscheme/src/char.c b/src/mzscheme/src/char.c index addddc6dfa..f360763ebd 100644 --- a/src/mzscheme/src/char.c +++ b/src/mzscheme/src/char.c @@ -246,7 +246,7 @@ void scheme_init_char (Scheme_Env *env) env); scheme_add_global_constant("make-known-char-range-list", - scheme_make_noncm_prim(char_map_list, + scheme_make_immed_prim(char_map_list, "make-known-char-range-list", 0, 0), env); diff --git a/src/mzscheme/src/cstartup.inc b/src/mzscheme/src/cstartup.inc index 95e2e69817..cd8f145ece 100644 --- a/src/mzscheme/src/cstartup.inc +++ b/src/mzscheme/src/cstartup.inc @@ -1,68 +1,72 @@ { - static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,8,51,46,57,57,46,48,46,57,50,0,0,0,1,0,0,6,0,9, -0,14,0,18,0,23,0,28,0,32,0,39,0,42,0,55,0,62,0,69,0, -78,0,84,0,98,0,112,0,115,0,119,0,121,0,132,0,134,0,148,0,155, -0,177,0,179,0,193,0,203,0,209,0,232,0,33,1,43,1,60,1,93,1, -126,1,185,1,230,1,52,2,97,2,102,2,122,2,252,2,16,3,64,3,130, -3,13,4,155,4,198,4,209,4,32,5,0,0,50,7,0,0,65,98,101,103, -105,110,29,11,11,64,108,101,116,42,63,108,101,116,64,119,104,101,110,64,99, -111,110,100,63,97,110,100,66,108,101,116,114,101,99,62,111,114,72,112,97,114, -97,109,101,116,101,114,105,122,101,66,100,101,102,105,110,101,66,117,110,108,101, -115,115,68,104,101,114,101,45,115,116,120,65,113,117,111,116,101,29,94,2,14, -68,35,37,112,97,114,97,109,122,11,29,94,2,14,68,35,37,107,101,114,110, -101,108,11,62,105,102,63,115,116,120,61,115,70,108,101,116,45,118,97,108,117, -101,115,61,120,73,108,101,116,114,101,99,45,118,97,108,117,101,115,66,108,97, -109,98,100,97,1,20,112,97,114,97,109,101,116,101,114,105,122,97,116,105,111, -110,45,107,101,121,61,118,73,100,101,102,105,110,101,45,118,97,108,117,101,115, -95,8,240,48,117,0,0,11,16,0,95,8,193,11,16,0,96,35,11,93,159, -2,16,34,35,16,2,2,13,161,2,2,35,2,13,2,2,2,13,97,10,34, -11,94,159,2,15,34,34,159,2,16,34,34,16,20,2,9,2,2,2,3,2, -2,2,4,2,2,2,5,2,2,2,10,2,2,2,7,2,2,2,8,2,2, -2,6,2,2,2,11,2,2,2,12,2,2,13,16,4,34,29,11,11,2,2, -11,18,98,64,104,101,114,101,8,31,8,30,8,29,8,28,8,27,27,248,22, -178,3,195,249,22,171,3,80,158,37,34,251,22,73,2,17,248,22,88,199,12, -249,22,63,2,1,248,22,90,201,27,248,22,178,3,195,249,22,171,3,80,158, -37,34,251,22,73,2,17,248,22,88,199,249,22,63,2,1,248,22,90,201,12, -27,248,22,65,248,22,178,3,196,28,248,22,71,193,20,15,159,35,34,35,28, -248,22,71,248,22,65,194,248,22,64,193,249,22,171,3,80,158,37,34,251,22, -73,2,17,248,22,64,199,249,22,63,2,7,248,22,65,201,11,18,100,10,8, -31,8,30,8,29,8,28,8,27,16,4,11,11,2,18,3,1,7,101,110,118, -54,55,55,56,16,4,11,11,2,19,3,1,7,101,110,118,54,55,55,57,27, -248,22,65,248,22,178,3,196,28,248,22,71,193,20,15,159,35,34,35,28,248, -22,71,248,22,65,194,248,22,64,193,249,22,171,3,80,158,37,34,250,22,73, -2,20,248,22,73,249,22,73,248,22,73,2,21,248,22,64,201,251,22,73,2, -17,2,21,2,21,249,22,63,2,9,248,22,65,204,18,100,11,8,31,8,30, -8,29,8,28,8,27,16,4,11,11,2,18,3,1,7,101,110,118,54,55,56, -49,16,4,11,11,2,19,3,1,7,101,110,118,54,55,56,50,248,22,178,3, -193,27,248,22,178,3,194,249,22,63,248,22,73,248,22,64,196,248,22,65,195, -27,248,22,65,248,22,178,3,196,249,22,171,3,80,158,37,34,28,248,22,51, -248,22,172,3,248,22,64,197,27,249,22,2,32,0,89,162,8,36,35,41,9, -222,33,39,248,22,178,3,248,22,88,199,250,22,73,2,22,248,22,73,249,22, -73,248,22,73,248,22,64,203,250,22,74,2,23,249,22,2,22,64,203,248,22, -90,205,249,22,63,248,22,64,201,249,22,2,22,88,199,250,22,74,2,20,249, -22,2,32,0,89,162,34,35,45,9,222,33,40,248,22,178,3,248,22,64,201, -248,22,65,198,27,248,22,178,3,194,249,22,63,248,22,73,248,22,64,196,248, -22,65,195,27,248,22,65,248,22,178,3,196,249,22,171,3,80,158,37,34,250, -22,74,2,22,249,22,2,32,0,89,162,34,35,45,9,222,33,42,248,22,178, -3,248,22,64,201,248,22,65,198,27,248,22,65,248,22,178,3,196,27,248,22, -178,3,248,22,64,195,249,22,171,3,80,158,38,34,28,248,22,71,195,250,22, -74,2,20,9,248,22,65,199,250,22,73,2,4,248,22,73,248,22,64,199,250, -22,74,2,3,248,22,65,201,248,22,65,202,27,248,22,65,248,22,178,3,196, + static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,51,46,57,57,46,48,46,49,49,50,0,0,0,1,0,0,6,0, +9,0,14,0,18,0,23,0,36,0,41,0,45,0,52,0,55,0,62,0,69, +0,78,0,84,0,98,0,112,0,115,0,119,0,121,0,132,0,134,0,148,0, +155,0,177,0,179,0,193,0,203,0,209,0,232,0,33,1,43,1,60,1,99, +1,138,1,212,1,1,2,94,2,139,2,144,2,164,2,54,3,74,3,124,3, +190,3,75,4,238,4,25,5,36,5,115,5,0,0,133,7,0,0,65,98,101, +103,105,110,29,11,11,64,108,101,116,42,63,108,101,116,64,119,104,101,110,72, +112,97,114,97,109,101,116,101,114,105,122,101,64,99,111,110,100,63,97,110,100, +66,108,101,116,114,101,99,62,111,114,66,100,101,102,105,110,101,66,117,110,108, +101,115,115,68,104,101,114,101,45,115,116,120,65,113,117,111,116,101,29,94,2, +14,68,35,37,112,97,114,97,109,122,11,29,94,2,14,68,35,37,107,101,114, +110,101,108,11,62,105,102,63,115,116,120,61,115,70,108,101,116,45,118,97,108, +117,101,115,61,120,73,108,101,116,114,101,99,45,118,97,108,117,101,115,66,108, +97,109,98,100,97,1,20,112,97,114,97,109,101,116,101,114,105,122,97,116,105, +111,110,45,107,101,121,61,118,73,100,101,102,105,110,101,45,118,97,108,117,101, +115,95,8,240,48,117,0,0,11,16,0,95,8,193,11,16,0,96,35,11,93, +159,2,16,34,35,16,2,2,13,161,2,2,35,2,13,2,2,2,13,97,10, +34,11,94,159,2,15,34,34,159,2,16,34,34,16,20,2,10,2,2,2,3, +2,2,2,4,2,2,2,5,2,2,2,6,2,2,2,7,2,2,2,8,2, +2,2,9,2,2,2,11,2,2,2,12,2,2,13,16,4,34,29,11,11,2, +2,11,18,98,64,104,101,114,101,8,31,8,30,8,29,8,28,8,27,27,248, +22,178,3,23,196,1,249,22,171,3,80,158,37,34,251,22,73,2,17,248,22, +88,23,200,2,12,249,22,63,2,1,248,22,90,23,202,1,27,248,22,178,3, +23,196,1,249,22,171,3,80,158,37,34,251,22,73,2,17,248,22,88,23,200, +2,249,22,63,2,1,248,22,90,23,202,1,12,27,248,22,65,248,22,178,3, +23,197,1,28,248,22,71,23,194,2,87,94,23,193,1,20,15,159,35,34,35, +28,248,22,71,248,22,65,23,195,2,248,22,64,193,249,22,171,3,80,158,37, +34,251,22,73,2,17,248,22,64,23,200,2,249,22,63,2,8,248,22,65,23, +202,1,11,18,100,10,8,31,8,30,8,29,8,28,8,27,16,4,11,11,2, +18,3,1,7,101,110,118,54,57,49,51,16,4,11,11,2,19,3,1,7,101, +110,118,54,57,49,52,27,248,22,65,248,22,178,3,23,197,1,28,248,22,71, +23,194,2,87,94,23,193,1,20,15,159,35,34,35,28,248,22,71,248,22,65, +23,195,2,248,22,64,193,249,22,171,3,80,158,37,34,250,22,73,2,20,248, +22,73,249,22,73,248,22,73,2,21,248,22,64,23,202,2,251,22,73,2,17, +2,21,2,21,249,22,63,2,10,248,22,65,23,205,1,18,100,11,8,31,8, +30,8,29,8,28,8,27,16,4,11,11,2,18,3,1,7,101,110,118,54,57, +49,54,16,4,11,11,2,19,3,1,7,101,110,118,54,57,49,55,248,22,178, +3,193,27,248,22,178,3,194,249,22,63,248,22,73,248,22,64,196,248,22,65, +195,27,248,22,65,248,22,178,3,23,197,1,249,22,171,3,80,158,37,34,28, +248,22,51,248,22,172,3,248,22,64,23,198,2,27,249,22,2,32,0,89,162, +8,44,35,41,9,222,33,39,248,22,178,3,248,22,88,23,200,2,250,22,73, +2,22,248,22,73,249,22,73,248,22,73,248,22,64,23,204,2,250,22,74,2, +23,249,22,2,22,64,23,204,2,248,22,90,23,206,2,249,22,63,248,22,64, +23,202,1,249,22,2,22,88,23,200,1,250,22,74,2,20,249,22,2,32,0, +89,162,42,35,45,9,222,33,40,248,22,178,3,248,22,64,201,248,22,65,198, +27,248,22,178,3,194,249,22,63,248,22,73,248,22,64,196,248,22,65,195,27, +248,22,65,248,22,178,3,23,197,1,249,22,171,3,80,158,37,34,250,22,74, +2,22,249,22,2,32,0,89,162,42,35,45,9,222,33,42,248,22,178,3,248, +22,64,201,248,22,65,198,27,248,22,65,248,22,178,3,196,27,248,22,178,3, +248,22,64,195,249,22,171,3,80,158,38,34,28,248,22,71,195,250,22,74,2, +20,9,248,22,65,199,250,22,73,2,4,248,22,73,248,22,64,199,250,22,74, +2,3,248,22,65,201,248,22,65,202,27,248,22,65,248,22,178,3,23,197,1, 27,249,22,1,22,77,249,22,2,22,178,3,248,22,178,3,248,22,64,199,249, 22,171,3,80,158,38,34,251,22,73,1,22,119,105,116,104,45,99,111,110,116, 105,110,117,97,116,105,111,110,45,109,97,114,107,2,24,250,22,74,1,23,101, 120,116,101,110,100,45,112,97,114,97,109,101,116,101,114,105,122,97,116,105,111, 110,21,95,1,27,99,111,110,116,105,110,117,97,116,105,111,110,45,109,97,114, 107,45,115,101,116,45,102,105,114,115,116,11,2,24,201,250,22,74,2,20,9, -248,22,65,203,27,248,22,65,248,22,178,3,196,28,248,22,71,193,20,15,159, -35,34,35,249,22,171,3,80,158,37,34,27,248,22,178,3,248,22,64,197,28, -249,22,137,8,62,61,62,248,22,172,3,248,22,88,196,250,22,73,2,20,248, -22,73,249,22,73,21,93,2,25,248,22,64,199,250,22,74,2,6,249,22,73, -2,25,249,22,73,248,22,97,203,2,25,248,22,65,202,251,22,73,2,17,28, -249,22,137,8,248,22,172,3,248,22,64,200,64,101,108,115,101,10,248,22,64, -197,250,22,74,2,20,9,248,22,65,200,249,22,63,2,6,248,22,65,202,99, +248,22,65,203,27,248,22,65,248,22,178,3,23,197,1,28,248,22,71,23,194, +2,87,94,23,193,1,20,15,159,35,34,35,249,22,171,3,80,158,37,34,27, +248,22,178,3,248,22,64,23,198,2,28,249,22,138,8,62,61,62,248,22,172, +3,248,22,88,23,197,2,250,22,73,2,20,248,22,73,249,22,73,21,93,2, +25,248,22,64,199,250,22,74,2,7,249,22,73,2,25,249,22,73,248,22,97, +203,2,25,248,22,65,202,251,22,73,2,17,28,249,22,138,8,248,22,172,3, +248,22,64,23,201,2,64,101,108,115,101,10,248,22,64,23,198,2,250,22,74, +2,20,9,248,22,65,23,201,1,249,22,63,2,7,248,22,65,23,203,1,99, 8,31,8,30,8,29,8,28,8,27,16,4,11,11,2,18,3,1,7,101,110, -118,54,56,48,52,16,4,11,11,2,19,3,1,7,101,110,118,54,56,48,53, +118,54,57,51,57,16,4,11,11,2,19,3,1,7,101,110,118,54,57,52,48, 18,158,94,10,64,118,111,105,100,8,47,27,248,22,65,248,22,178,3,196,249, 22,171,3,80,158,37,34,28,248,22,51,248,22,172,3,248,22,64,197,250,22, 73,2,26,248,22,73,248,22,64,199,248,22,88,198,27,248,22,172,3,248,22, @@ -75,187 +79,187 @@ 6,2,7,2,8,2,9,2,10,2,11,2,12,16,10,11,11,11,11,11,11, 11,11,11,11,16,10,2,3,2,4,2,5,2,6,2,7,2,8,2,9,2, 10,2,11,2,12,34,44,16,11,16,5,93,2,13,20,15,159,34,34,34,34, -20,102,159,34,16,0,16,1,33,32,10,16,5,93,2,12,89,162,8,36,35, +20,102,159,34,16,0,16,1,33,32,10,16,5,93,2,12,89,162,8,44,35, 51,9,223,0,33,33,34,20,102,159,34,16,1,20,25,159,35,2,2,2,13, -16,0,11,16,5,93,2,5,89,162,8,36,35,51,9,223,0,33,34,34,20, -102,159,34,16,1,20,25,159,35,2,2,2,13,16,0,11,16,5,93,2,7, -89,162,8,36,35,51,9,223,0,33,35,34,20,102,159,34,16,1,20,25,159, -35,2,2,2,13,16,1,33,36,11,16,5,93,2,9,89,162,8,36,35,54, +16,0,11,16,5,93,2,5,89,162,8,44,35,51,9,223,0,33,34,34,20, +102,159,34,16,1,20,25,159,35,2,2,2,13,16,0,11,16,5,93,2,8, +89,162,8,44,35,51,9,223,0,33,35,34,20,102,159,34,16,1,20,25,159, +35,2,2,2,13,16,1,33,36,11,16,5,93,2,10,89,162,8,44,35,54, 9,223,0,33,37,34,20,102,159,34,16,1,20,25,159,35,2,2,2,13,16, -1,33,38,11,16,5,93,2,4,89,162,8,36,35,56,9,223,0,33,41,34, +1,33,38,11,16,5,93,2,4,89,162,8,44,35,56,9,223,0,33,41,34, 20,102,159,34,16,1,20,25,159,35,2,2,2,13,16,0,11,16,5,93,2, -8,89,162,8,36,35,51,9,223,0,33,43,34,20,102,159,34,16,1,20,25, -159,35,2,2,2,13,16,0,11,16,5,93,2,3,89,162,8,36,35,52,9, +9,89,162,8,44,35,51,9,223,0,33,43,34,20,102,159,34,16,1,20,25, +159,35,2,2,2,13,16,0,11,16,5,93,2,3,89,162,8,44,35,52,9, 223,0,33,44,34,20,102,159,34,16,1,20,25,159,35,2,2,2,13,16,0, -11,16,5,93,2,10,89,162,8,36,35,53,9,223,0,33,45,34,20,102,159, -34,16,1,20,25,159,35,2,2,2,13,16,0,11,16,5,93,2,6,89,162, -8,36,35,56,9,223,0,33,46,34,20,102,159,34,16,1,20,25,159,35,2, -2,2,13,16,1,33,48,11,16,5,93,2,11,89,162,8,36,35,52,9,223, +11,16,5,93,2,6,89,162,8,44,35,53,9,223,0,33,45,34,20,102,159, +34,16,1,20,25,159,35,2,2,2,13,16,0,11,16,5,93,2,7,89,162, +8,44,35,56,9,223,0,33,46,34,20,102,159,34,16,1,20,25,159,35,2, +2,2,13,16,1,33,48,11,16,5,93,2,11,89,162,8,44,35,52,9,223, 0,33,49,34,20,102,159,34,16,1,20,25,159,35,2,2,2,13,16,0,11, 16,0,94,2,16,2,15,93,2,16,9,0}; - EVAL_ONE_SIZED_STR((char *)expr, 1964); + EVAL_ONE_SIZED_STR((char *)expr, 2048); } { - static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,8,51,46,57,57,46,48,46,57,61,0,0,0,1,0,0,3,0,16, -0,21,0,38,0,53,0,71,0,87,0,97,0,115,0,135,0,151,0,169,0, -200,0,229,0,251,0,9,1,15,1,29,1,34,1,44,1,52,1,80,1,112, -1,157,1,202,1,226,1,9,2,11,2,20,2,71,2,87,3,96,3,126,3, -170,4,242,4,58,5,146,5,158,5,201,5,217,5,204,6,218,6,69,7,8, -8,202,8,209,8,215,8,75,9,87,9,155,9,1,10,14,10,36,10,170,10, -36,11,37,12,45,12,53,12,79,12,159,12,0,0,210,15,0,0,29,11,11, -72,112,97,116,104,45,115,116,114,105,110,103,63,64,98,115,98,115,76,110,111, -114,109,97,108,45,99,97,115,101,45,112,97,116,104,74,45,99,104,101,99,107, -45,114,101,108,112,97,116,104,77,45,99,104,101,99,107,45,99,111,108,108,101, -99,116,105,111,110,75,99,111,108,108,101,99,116,105,111,110,45,112,97,116,104, -69,45,102,105,110,100,45,99,111,108,77,99,104,101,99,107,45,115,117,102,102, -105,120,45,99,97,108,108,79,112,97,116,104,45,114,101,112,108,97,99,101,45, -115,117,102,102,105,120,75,112,97,116,104,45,97,100,100,45,115,117,102,102,105, -120,77,108,111,97,100,47,117,115,101,45,99,111,109,112,105,108,101,100,1,29, -102,105,110,100,45,108,105,98,114,97,114,121,45,99,111,108,108,101,99,116,105, -111,110,45,112,97,116,104,115,1,27,112,97,116,104,45,108,105,115,116,45,115, -116,114,105,110,103,45,62,112,97,116,104,45,108,105,115,116,1,20,102,105,110, -100,45,101,120,101,99,117,116,97,98,108,101,45,112,97,116,104,73,101,109,98, -101,100,100,101,100,45,108,111,97,100,65,113,117,111,116,101,29,94,2,17,68, -35,37,112,97,114,97,109,122,11,64,108,111,111,112,69,101,120,101,99,45,102, -105,108,101,67,119,105,110,100,111,119,115,6,25,25,112,97,116,104,32,111,114, -32,118,97,108,105,100,45,112,97,116,104,32,115,116,114,105,110,103,6,29,29, -126,97,58,32,105,110,118,97,108,105,100,32,114,101,108,97,116,105,118,101,32, -112,97,116,104,58,32,126,115,6,42,42,126,97,58,32,99,111,108,108,101,99, -116,105,111,110,32,110,111,116,32,102,111,117,110,100,58,32,126,115,32,105,110, -32,97,110,121,32,111,102,58,32,126,115,6,42,42,112,97,116,104,32,40,102, -111,114,32,97,110,121,32,115,121,115,116,101,109,41,32,111,114,32,118,97,108, -105,100,45,112,97,116,104,32,115,116,114,105,110,103,6,21,21,115,116,114,105, -110,103,32,111,114,32,98,121,116,101,32,115,116,114,105,110,103,6,36,36,99, -97,110,110,111,116,32,97,100,100,32,97,32,115,117,102,102,105,120,32,116,111, -32,97,32,114,111,111,116,32,112,97,116,104,58,32,5,0,68,35,37,107,101, -114,110,101,108,27,20,14,159,80,158,35,49,250,80,158,38,50,249,22,27,11, -80,158,40,49,22,137,12,10,248,22,186,4,195,28,248,22,164,5,193,12,87, -94,248,22,140,8,193,248,80,159,36,53,35,195,28,248,22,71,194,9,27,248, -22,64,195,27,28,248,22,182,12,194,193,28,248,22,181,12,194,249,22,183,12, -195,250,80,158,41,47,248,22,133,13,2,20,11,10,250,80,158,39,47,248,22, -133,13,2,20,196,10,28,192,249,22,63,248,22,185,12,249,22,183,12,197,247, -22,134,13,27,248,22,65,199,28,248,22,71,193,9,27,248,22,64,194,27,28, -248,22,182,12,194,193,28,248,22,181,12,194,249,22,183,12,195,250,80,158,46, -47,248,22,133,13,2,20,11,10,250,80,158,44,47,248,22,133,13,2,20,196, -10,28,192,249,22,63,248,22,185,12,249,22,183,12,197,247,22,134,13,248,80, -159,44,52,35,248,22,65,198,248,80,159,42,52,35,248,22,65,196,27,248,22, -65,197,28,248,22,71,193,9,27,248,22,64,194,27,28,248,22,182,12,194,193, -28,248,22,181,12,194,249,22,183,12,195,250,80,158,44,47,248,22,133,13,2, -20,11,10,250,80,158,42,47,248,22,133,13,2,20,196,10,28,192,249,22,63, -248,22,185,12,249,22,183,12,197,247,22,134,13,248,80,159,42,52,35,248,22, -65,198,248,80,159,40,52,35,248,22,65,196,249,80,159,36,37,35,2,7,195, -27,248,22,158,12,194,28,192,192,28,248,22,133,6,194,27,248,22,180,12,195, -28,192,192,248,22,181,12,195,11,87,94,28,28,248,22,159,12,194,10,27,248, -22,158,12,195,28,192,192,28,248,22,133,6,195,27,248,22,180,12,196,28,192, -192,248,22,181,12,196,11,12,250,22,167,8,76,110,111,114,109,97,108,45,112, -97,116,104,45,99,97,115,101,6,42,42,112,97,116,104,32,40,102,111,114,32, -97,110,121,32,115,121,115,116,101,109,41,32,111,114,32,118,97,108,105,100,45, -112,97,116,104,32,115,116,114,105,110,103,196,28,28,248,22,159,12,194,249,22, -137,8,248,22,160,12,196,2,21,249,22,137,8,247,22,152,7,2,21,27,28, -248,22,133,6,195,194,248,22,142,7,248,22,163,12,196,28,249,22,146,13,0, -21,35,114,120,34,94,91,92,92,93,91,92,92,93,91,63,93,91,92,92,93, -34,194,28,248,22,133,6,195,248,22,166,12,195,194,27,248,22,172,6,194,249, -22,167,12,248,22,145,7,250,22,152,13,0,6,35,114,120,34,47,34,28,249, -22,146,13,0,22,35,114,120,34,91,47,92,92,93,91,46,32,93,43,91,47, -92,92,93,42,36,34,200,198,250,22,152,13,0,19,35,114,120,34,91,32,46, -93,43,40,91,47,92,92,93,42,41,36,34,201,6,2,2,92,49,80,158,42, -35,2,21,28,248,22,133,6,194,248,22,166,12,194,193,87,94,28,27,248,22, -158,12,195,28,192,192,28,248,22,133,6,195,27,248,22,180,12,196,28,192,192, -248,22,181,12,196,11,12,250,22,167,8,195,2,22,196,28,248,22,180,12,194, -12,248,22,182,10,249,22,191,9,248,22,162,6,250,22,181,6,2,23,199,200, -247,22,23,87,94,28,27,248,22,158,12,195,28,192,192,28,248,22,133,6,195, -27,248,22,180,12,196,28,192,192,248,22,181,12,196,11,12,250,22,167,8,195, -2,22,196,28,248,22,180,12,194,12,248,22,182,10,249,22,191,9,248,22,162, -6,250,22,181,6,2,23,199,200,247,22,23,87,94,87,94,28,27,248,22,158, -12,195,28,192,192,28,248,22,133,6,195,27,248,22,180,12,196,28,192,192,248, -22,181,12,196,11,12,250,22,167,8,195,2,22,196,28,248,22,180,12,194,12, -248,22,182,10,249,22,191,9,248,22,162,6,250,22,181,6,2,23,199,200,247, -22,23,249,22,3,89,162,34,35,48,9,223,2,33,36,196,248,22,182,10,249, -22,157,10,195,247,22,23,87,94,87,94,249,80,159,36,37,35,2,7,195,249, -22,3,80,159,36,51,35,196,251,80,159,38,40,35,2,7,32,0,89,162,34, -35,43,9,222,33,38,197,198,32,40,89,162,34,40,57,65,99,108,111,111,112, -222,33,41,28,248,22,71,198,248,195,251,22,181,6,2,24,198,28,248,22,71, -202,200,250,22,1,22,176,12,203,204,197,27,249,22,176,12,248,22,64,201,198, -28,248,22,171,12,193,27,250,22,1,22,176,12,196,201,28,248,22,171,12,193, -192,27,248,22,65,201,28,248,22,71,193,248,198,251,22,181,6,2,24,201,28, -248,22,71,205,203,250,22,1,22,176,12,206,23,15,200,27,249,22,176,12,248, -22,64,196,201,28,248,22,171,12,193,27,250,22,1,22,176,12,196,204,28,248, -22,171,12,193,192,253,2,40,203,204,205,206,23,15,248,22,65,201,253,2,40, -202,203,204,205,206,248,22,65,200,27,248,22,65,200,28,248,22,71,193,248,197, -251,22,181,6,2,24,200,28,248,22,71,204,202,250,22,1,22,176,12,205,206, -199,27,249,22,176,12,248,22,64,196,200,28,248,22,171,12,193,27,250,22,1, -22,176,12,196,203,28,248,22,171,12,193,192,253,2,40,202,203,204,205,206,248, -22,65,201,253,2,40,201,202,203,204,205,248,22,65,200,27,247,22,135,13,253, -2,40,198,199,200,201,202,198,87,95,28,28,248,22,159,12,193,10,27,248,22, -158,12,194,28,192,192,28,248,22,133,6,194,27,248,22,180,12,195,28,192,192, -248,22,181,12,195,11,12,252,22,167,8,199,2,25,34,197,198,28,28,248,22, -133,6,194,10,248,22,185,6,194,12,252,22,167,8,199,2,26,35,197,198,91, -159,37,11,90,161,37,34,11,248,22,179,12,196,87,94,28,192,12,250,22,168, -8,200,2,27,198,249,22,7,194,195,91,159,36,11,90,161,36,34,11,87,95, -28,28,248,22,159,12,195,10,27,248,22,158,12,196,28,192,192,28,248,22,133, -6,196,27,248,22,180,12,197,28,192,192,248,22,181,12,197,11,12,252,22,167, -8,2,10,2,25,34,199,200,28,28,248,22,133,6,196,10,248,22,185,6,196, -12,252,22,167,8,2,10,2,26,35,199,200,91,159,37,11,90,161,37,34,11, -248,22,179,12,198,87,94,28,192,12,250,22,168,8,2,10,2,27,200,249,22, -7,194,195,27,249,22,168,12,250,22,151,13,0,18,35,114,120,35,34,40,91, -46,93,91,94,46,93,42,124,41,36,34,248,22,164,12,200,28,248,22,133,6, -202,249,22,145,7,203,8,63,201,28,248,22,159,12,198,248,22,160,12,198,247, -22,161,12,28,248,22,158,12,194,249,22,176,12,195,194,192,91,159,36,11,90, -161,36,34,11,87,95,28,28,248,22,159,12,195,10,27,248,22,158,12,196,28, -192,192,28,248,22,133,6,196,27,248,22,180,12,197,28,192,192,248,22,181,12, -197,11,12,252,22,167,8,2,11,2,25,34,199,200,28,28,248,22,133,6,196, -10,248,22,185,6,196,12,252,22,167,8,2,11,2,26,35,199,200,91,159,37, -11,90,161,37,34,11,248,22,179,12,198,87,94,28,192,12,250,22,168,8,2, -11,2,27,200,249,22,7,194,195,27,249,22,168,12,249,22,131,7,250,22,152, -13,0,9,35,114,120,35,34,91,46,93,34,248,22,164,12,202,6,1,1,95, -28,248,22,133,6,201,249,22,145,7,202,8,63,200,28,248,22,159,12,198,248, -22,160,12,198,247,22,161,12,28,248,22,158,12,194,249,22,176,12,195,194,192, -249,247,22,184,5,194,11,248,80,158,35,45,9,27,247,22,137,13,249,80,158, -37,46,28,194,27,248,22,150,7,6,11,11,80,76,84,67,79,76,76,69,67, -84,83,28,192,192,6,0,0,6,0,0,27,28,195,250,22,176,12,248,22,133, -13,69,97,100,100,111,110,45,100,105,114,247,22,148,7,6,8,8,99,111,108, -108,101,99,116,115,11,27,248,80,159,40,52,35,249,22,77,201,248,22,73,248, -22,133,13,72,99,111,108,108,101,99,116,115,45,100,105,114,28,193,249,22,63, -195,194,192,32,49,89,162,34,37,49,2,19,222,33,50,27,249,22,144,13,196, -197,28,192,27,248,22,88,194,27,250,2,49,198,199,248,22,97,198,28,249,22, -191,6,195,2,28,249,22,77,197,194,249,22,63,248,22,167,12,196,194,28,249, -22,191,6,197,2,28,249,22,77,195,9,249,22,63,248,22,167,12,198,9,87, -95,28,28,248,22,185,6,194,10,248,22,133,6,194,12,250,22,167,8,2,14, -6,21,21,98,121,116,101,32,115,116,114,105,110,103,32,111,114,32,115,116,114, -105,110,103,196,28,28,248,22,72,195,249,22,4,22,158,12,196,11,12,250,22, -167,8,2,14,6,13,13,108,105,115,116,32,111,102,32,112,97,116,104,115,197, -250,2,49,197,195,28,248,22,133,6,197,248,22,144,7,197,196,32,52,89,162, -8,36,38,56,2,19,222,33,55,32,53,89,162,8,36,37,53,70,102,111,117, -110,100,45,101,120,101,99,222,33,54,28,192,91,159,37,11,90,161,37,34,11, -248,22,179,12,198,27,28,197,27,248,22,184,12,200,28,249,22,139,8,194,201, -11,28,248,22,180,12,193,250,2,53,200,201,249,22,176,12,199,197,250,2,53, -200,201,195,11,28,192,192,27,28,248,22,158,12,195,27,249,22,176,12,197,200, -28,28,248,22,171,12,193,10,248,22,170,12,193,192,11,11,28,192,192,28,198, -11,27,248,22,184,12,201,28,249,22,139,8,194,202,11,28,248,22,180,12,193, -250,2,53,201,202,249,22,176,12,200,197,250,2,53,201,202,195,194,28,248,22, -71,196,11,27,248,22,183,12,248,22,64,198,27,249,22,176,12,195,196,28,248, -22,170,12,193,250,2,53,198,199,195,27,248,22,65,199,28,248,22,71,193,11, -27,248,22,183,12,248,22,64,195,27,249,22,176,12,195,199,28,248,22,170,12, -193,250,2,53,201,202,195,27,248,22,65,196,28,248,22,71,193,11,27,248,22, -183,12,248,22,64,195,27,249,22,176,12,195,202,28,248,22,170,12,193,250,2, -53,204,205,195,251,2,52,204,205,206,248,22,65,199,87,95,28,27,248,22,158, -12,195,28,192,192,28,248,22,133,6,195,27,248,22,180,12,196,28,192,192,248, -22,181,12,196,11,12,250,22,167,8,2,15,6,25,25,112,97,116,104,32,111, -114,32,115,116,114,105,110,103,32,40,115,97,110,115,32,110,117,108,41,196,28, -28,194,28,27,248,22,158,12,196,28,192,192,28,248,22,133,6,196,27,248,22, -180,12,197,28,192,192,248,22,181,12,197,11,248,22,180,12,195,11,10,12,250, -22,167,8,2,15,6,29,29,35,102,32,111,114,32,114,101,108,97,116,105,118, -101,32,112,97,116,104,32,111,114,32,115,116,114,105,110,103,197,28,28,248,22, -180,12,194,91,159,37,11,90,161,37,34,11,248,22,179,12,197,249,22,137,8, -194,68,114,101,108,97,116,105,118,101,11,27,248,22,150,7,6,4,4,80,65, -84,72,251,2,52,198,199,200,28,196,27,249,80,158,42,46,199,9,28,249,22, -137,8,247,22,152,7,2,21,249,22,63,248,22,167,12,5,1,46,194,192,9, -27,248,22,183,12,195,28,248,22,170,12,193,250,2,53,198,199,195,11,250,80, -158,37,47,196,197,11,250,80,158,37,47,196,11,11,87,94,249,22,189,5,247, -22,166,4,195,248,22,140,5,249,22,151,3,34,249,22,135,3,197,198,27,248, -22,133,13,2,20,27,249,80,158,38,47,195,11,27,27,248,22,154,3,198,28, -192,192,34,27,27,248,22,154,3,200,28,192,192,34,27,249,22,183,4,197,89, -162,8,36,34,46,9,224,4,3,33,59,27,248,22,170,4,194,87,94,248,22, + static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,51,46,57,57,46,48,46,49,49,61,0,0,0,1,0,0,3,0, +16,0,21,0,38,0,53,0,71,0,87,0,97,0,115,0,135,0,151,0,169, +0,200,0,229,0,251,0,9,1,15,1,29,1,34,1,44,1,52,1,80,1, +112,1,157,1,202,1,226,1,9,2,11,2,20,2,71,2,87,3,96,3,126, +3,170,4,242,4,58,5,146,5,158,5,201,5,217,5,204,6,218,6,69,7, +8,8,202,8,209,8,215,8,75,9,87,9,155,9,1,10,14,10,36,10,170, +10,36,11,37,12,45,12,53,12,79,12,158,12,0,0,209,15,0,0,29,11, +11,72,112,97,116,104,45,115,116,114,105,110,103,63,64,98,115,98,115,76,110, +111,114,109,97,108,45,99,97,115,101,45,112,97,116,104,74,45,99,104,101,99, +107,45,114,101,108,112,97,116,104,77,45,99,104,101,99,107,45,99,111,108,108, +101,99,116,105,111,110,75,99,111,108,108,101,99,116,105,111,110,45,112,97,116, +104,69,45,102,105,110,100,45,99,111,108,77,99,104,101,99,107,45,115,117,102, +102,105,120,45,99,97,108,108,79,112,97,116,104,45,114,101,112,108,97,99,101, +45,115,117,102,102,105,120,75,112,97,116,104,45,97,100,100,45,115,117,102,102, +105,120,77,108,111,97,100,47,117,115,101,45,99,111,109,112,105,108,101,100,1, +29,102,105,110,100,45,108,105,98,114,97,114,121,45,99,111,108,108,101,99,116, +105,111,110,45,112,97,116,104,115,1,27,112,97,116,104,45,108,105,115,116,45, +115,116,114,105,110,103,45,62,112,97,116,104,45,108,105,115,116,1,20,102,105, +110,100,45,101,120,101,99,117,116,97,98,108,101,45,112,97,116,104,73,101,109, +98,101,100,100,101,100,45,108,111,97,100,65,113,117,111,116,101,29,94,2,17, +68,35,37,112,97,114,97,109,122,11,64,108,111,111,112,69,101,120,101,99,45, +102,105,108,101,67,119,105,110,100,111,119,115,6,25,25,112,97,116,104,32,111, +114,32,118,97,108,105,100,45,112,97,116,104,32,115,116,114,105,110,103,6,29, +29,126,97,58,32,105,110,118,97,108,105,100,32,114,101,108,97,116,105,118,101, +32,112,97,116,104,58,32,126,115,6,42,42,126,97,58,32,99,111,108,108,101, +99,116,105,111,110,32,110,111,116,32,102,111,117,110,100,58,32,126,115,32,105, +110,32,97,110,121,32,111,102,58,32,126,115,6,42,42,112,97,116,104,32,40, +102,111,114,32,97,110,121,32,115,121,115,116,101,109,41,32,111,114,32,118,97, +108,105,100,45,112,97,116,104,32,115,116,114,105,110,103,6,21,21,115,116,114, +105,110,103,32,111,114,32,98,121,116,101,32,115,116,114,105,110,103,6,36,36, +99,97,110,110,111,116,32,97,100,100,32,97,32,115,117,102,102,105,120,32,116, +111,32,97,32,114,111,111,116,32,112,97,116,104,58,32,5,0,68,35,37,107, +101,114,110,101,108,27,20,14,159,80,158,35,49,250,80,158,38,50,249,22,27, +11,80,158,40,49,22,138,12,10,248,22,186,4,195,28,248,22,164,5,193,12, +87,94,248,22,141,8,193,248,80,159,36,53,35,195,28,248,22,71,194,9,27, +248,22,64,195,27,28,248,22,183,12,194,193,28,248,22,182,12,194,249,22,184, +12,195,250,80,158,41,47,248,22,134,13,2,20,11,10,250,80,158,39,47,248, +22,134,13,2,20,196,10,28,192,249,22,63,248,22,186,12,249,22,184,12,197, +247,22,135,13,27,248,22,65,199,28,248,22,71,193,9,27,248,22,64,194,27, +28,248,22,183,12,194,193,28,248,22,182,12,194,249,22,184,12,195,250,80,158, +46,47,248,22,134,13,2,20,11,10,250,80,158,44,47,248,22,134,13,2,20, +196,10,28,192,249,22,63,248,22,186,12,249,22,184,12,197,247,22,135,13,248, +80,159,44,52,35,248,22,65,198,248,80,159,42,52,35,248,22,65,196,27,248, +22,65,197,28,248,22,71,193,9,27,248,22,64,194,27,28,248,22,183,12,194, +193,28,248,22,182,12,194,249,22,184,12,195,250,80,158,44,47,248,22,134,13, +2,20,11,10,250,80,158,42,47,248,22,134,13,2,20,196,10,28,192,249,22, +63,248,22,186,12,249,22,184,12,197,247,22,135,13,248,80,159,42,52,35,248, +22,65,198,248,80,159,40,52,35,248,22,65,196,249,80,159,36,37,35,2,7, +195,27,248,22,159,12,194,28,192,192,28,248,22,133,6,194,27,248,22,181,12, +195,28,192,192,248,22,182,12,195,11,87,94,28,28,248,22,160,12,194,10,27, +248,22,159,12,195,28,192,192,28,248,22,133,6,195,27,248,22,181,12,196,28, +192,192,248,22,182,12,196,11,12,250,22,168,8,76,110,111,114,109,97,108,45, +112,97,116,104,45,99,97,115,101,6,42,42,112,97,116,104,32,40,102,111,114, +32,97,110,121,32,115,121,115,116,101,109,41,32,111,114,32,118,97,108,105,100, +45,112,97,116,104,32,115,116,114,105,110,103,196,28,28,248,22,160,12,194,249, +22,138,8,248,22,161,12,196,2,21,249,22,138,8,247,22,152,7,2,21,27, +28,248,22,133,6,195,194,248,22,142,7,248,22,164,12,196,28,249,22,147,13, +0,21,35,114,120,34,94,91,92,92,93,91,92,92,93,91,63,93,91,92,92, +93,34,194,28,248,22,133,6,195,248,22,167,12,195,194,27,248,22,172,6,194, +249,22,168,12,248,22,145,7,250,22,153,13,0,6,35,114,120,34,47,34,28, +249,22,147,13,0,22,35,114,120,34,91,47,92,92,93,91,46,32,93,43,91, +47,92,92,93,42,36,34,200,198,250,22,153,13,0,19,35,114,120,34,91,32, +46,93,43,40,91,47,92,92,93,42,41,36,34,201,6,2,2,92,49,80,158, +42,35,2,21,28,248,22,133,6,194,248,22,167,12,194,193,87,94,28,27,248, +22,159,12,195,28,192,192,28,248,22,133,6,195,27,248,22,181,12,196,28,192, +192,248,22,182,12,196,11,12,250,22,168,8,195,2,22,196,28,248,22,181,12, +194,12,248,22,183,10,249,22,128,10,248,22,162,6,250,22,181,6,2,23,199, +200,247,22,23,87,94,28,27,248,22,159,12,195,28,192,192,28,248,22,133,6, +195,27,248,22,181,12,196,28,192,192,248,22,182,12,196,11,12,250,22,168,8, +195,2,22,196,28,248,22,181,12,194,12,248,22,183,10,249,22,128,10,248,22, +162,6,250,22,181,6,2,23,199,200,247,22,23,87,94,87,94,28,27,248,22, +159,12,195,28,192,192,28,248,22,133,6,195,27,248,22,181,12,196,28,192,192, +248,22,182,12,196,11,12,250,22,168,8,195,2,22,196,28,248,22,181,12,194, +12,248,22,183,10,249,22,128,10,248,22,162,6,250,22,181,6,2,23,199,200, +247,22,23,249,22,3,89,162,34,35,48,9,223,2,33,36,196,248,22,183,10, +249,22,158,10,195,247,22,23,87,94,87,94,249,80,159,36,37,35,2,7,195, +249,22,3,80,159,36,51,35,196,251,80,159,38,40,35,2,7,32,0,89,162, +34,35,43,9,222,33,38,197,198,32,40,89,162,34,40,57,65,99,108,111,111, +112,222,33,41,28,248,22,71,198,248,195,251,22,181,6,2,24,198,28,248,22, +71,202,200,250,22,1,22,177,12,203,204,197,27,249,22,177,12,248,22,64,201, +198,28,248,22,172,12,193,27,250,22,1,22,177,12,196,201,28,248,22,172,12, +193,192,27,248,22,65,201,28,248,22,71,193,248,198,251,22,181,6,2,24,201, +28,248,22,71,205,203,250,22,1,22,177,12,206,23,15,200,27,249,22,177,12, +248,22,64,196,201,28,248,22,172,12,193,27,250,22,1,22,177,12,196,204,28, +248,22,172,12,193,192,253,2,40,203,204,205,206,23,15,248,22,65,201,253,2, +40,202,203,204,205,206,248,22,65,200,27,248,22,65,200,28,248,22,71,193,248, +197,251,22,181,6,2,24,200,28,248,22,71,204,202,250,22,1,22,177,12,205, +206,199,27,249,22,177,12,248,22,64,196,200,28,248,22,172,12,193,27,250,22, +1,22,177,12,196,203,28,248,22,172,12,193,192,253,2,40,202,203,204,205,206, +248,22,65,201,253,2,40,201,202,203,204,205,248,22,65,200,27,247,22,136,13, +253,2,40,198,199,200,201,202,198,87,95,28,28,248,22,160,12,193,10,27,248, +22,159,12,194,28,192,192,28,248,22,133,6,194,27,248,22,181,12,195,28,192, +192,248,22,182,12,195,11,12,252,22,168,8,199,2,25,34,197,198,28,28,248, +22,133,6,194,10,248,22,185,6,194,12,252,22,168,8,199,2,26,35,197,198, +91,159,37,11,90,161,37,34,11,248,22,180,12,196,87,94,28,192,12,250,22, +169,8,200,2,27,198,249,22,7,194,195,91,159,36,11,90,161,36,34,11,87, +95,28,28,248,22,160,12,195,10,27,248,22,159,12,196,28,192,192,28,248,22, +133,6,196,27,248,22,181,12,197,28,192,192,248,22,182,12,197,11,12,252,22, +168,8,2,10,2,25,34,199,200,28,28,248,22,133,6,196,10,248,22,185,6, +196,12,252,22,168,8,2,10,2,26,35,199,200,91,159,37,11,90,161,37,34, +11,248,22,180,12,198,87,94,28,192,12,250,22,169,8,2,10,2,27,200,249, +22,7,194,195,27,249,22,169,12,250,22,152,13,0,18,35,114,120,35,34,40, +91,46,93,91,94,46,93,42,124,41,36,34,248,22,165,12,200,28,248,22,133, +6,202,249,22,145,7,203,8,63,201,28,248,22,160,12,198,248,22,161,12,198, +247,22,162,12,28,248,22,159,12,194,249,22,177,12,195,194,192,91,159,36,11, +90,161,36,34,11,87,95,28,28,248,22,160,12,195,10,27,248,22,159,12,196, +28,192,192,28,248,22,133,6,196,27,248,22,181,12,197,28,192,192,248,22,182, +12,197,11,12,252,22,168,8,2,11,2,25,34,199,200,28,28,248,22,133,6, +196,10,248,22,185,6,196,12,252,22,168,8,2,11,2,26,35,199,200,91,159, +37,11,90,161,37,34,11,248,22,180,12,198,87,94,28,192,12,250,22,169,8, +2,11,2,27,200,249,22,7,194,195,27,249,22,169,12,249,22,131,7,250,22, +153,13,0,9,35,114,120,35,34,91,46,93,34,248,22,165,12,202,6,1,1, +95,28,248,22,133,6,201,249,22,145,7,202,8,63,200,28,248,22,160,12,198, +248,22,161,12,198,247,22,162,12,28,248,22,159,12,194,249,22,177,12,195,194, +192,249,247,22,184,5,194,11,248,80,158,35,45,9,27,247,22,138,13,249,80, +158,37,46,28,194,27,248,22,150,7,6,11,11,80,76,84,67,79,76,76,69, +67,84,83,28,192,192,6,0,0,6,0,0,27,28,195,250,22,177,12,248,22, +134,13,69,97,100,100,111,110,45,100,105,114,247,22,148,7,6,8,8,99,111, +108,108,101,99,116,115,11,27,248,80,159,40,52,35,249,22,77,201,248,22,73, +248,22,134,13,72,99,111,108,108,101,99,116,115,45,100,105,114,28,193,249,22, +63,195,194,192,32,49,89,162,34,37,49,2,19,222,33,50,27,249,22,145,13, +196,197,28,192,27,248,22,88,194,27,250,2,49,198,199,248,22,97,198,28,249, +22,191,6,195,2,28,249,22,77,197,194,249,22,63,248,22,168,12,196,194,28, +249,22,191,6,197,2,28,249,22,77,195,9,249,22,63,248,22,168,12,198,9, +87,95,28,28,248,22,185,6,194,10,248,22,133,6,194,12,250,22,168,8,2, +14,6,21,21,98,121,116,101,32,115,116,114,105,110,103,32,111,114,32,115,116, +114,105,110,103,196,28,28,248,22,72,195,249,22,4,22,159,12,196,11,12,250, +22,168,8,2,14,6,13,13,108,105,115,116,32,111,102,32,112,97,116,104,115, +197,250,2,49,197,195,28,248,22,133,6,197,248,22,144,7,197,196,32,52,89, +162,8,36,38,56,2,19,222,33,55,32,53,89,162,8,36,37,53,70,102,111, +117,110,100,45,101,120,101,99,222,33,54,28,192,91,159,37,11,90,161,37,34, +11,248,22,180,12,198,27,28,197,27,248,22,185,12,200,28,249,22,140,8,194, +201,11,28,248,22,181,12,193,250,2,53,200,201,249,22,177,12,199,197,250,2, +53,200,201,195,11,28,192,192,27,28,248,22,159,12,195,27,249,22,177,12,197, +200,28,28,248,22,172,12,193,10,248,22,171,12,193,192,11,11,28,192,192,28, +198,11,27,248,22,185,12,201,28,249,22,140,8,194,202,11,28,248,22,181,12, +193,250,2,53,201,202,249,22,177,12,200,197,250,2,53,201,202,195,194,28,248, +22,71,196,11,27,248,22,184,12,248,22,64,198,27,249,22,177,12,195,196,28, +248,22,171,12,193,250,2,53,198,199,195,27,248,22,65,199,28,248,22,71,193, +11,27,248,22,184,12,248,22,64,195,27,249,22,177,12,195,199,28,248,22,171, +12,193,250,2,53,201,202,195,27,248,22,65,196,28,248,22,71,193,11,27,248, +22,184,12,248,22,64,195,27,249,22,177,12,195,202,28,248,22,171,12,193,250, +2,53,204,205,195,251,2,52,204,205,206,248,22,65,199,87,95,28,27,248,22, +159,12,195,28,192,192,28,248,22,133,6,195,27,248,22,181,12,196,28,192,192, +248,22,182,12,196,11,12,250,22,168,8,2,15,6,25,25,112,97,116,104,32, +111,114,32,115,116,114,105,110,103,32,40,115,97,110,115,32,110,117,108,41,196, +28,28,194,28,27,248,22,159,12,196,28,192,192,28,248,22,133,6,196,27,248, +22,181,12,197,28,192,192,248,22,182,12,197,11,248,22,181,12,195,11,10,12, +250,22,168,8,2,15,6,29,29,35,102,32,111,114,32,114,101,108,97,116,105, +118,101,32,112,97,116,104,32,111,114,32,115,116,114,105,110,103,197,28,28,248, +22,181,12,194,91,159,37,11,90,161,37,34,11,248,22,180,12,197,249,22,138, +8,194,68,114,101,108,97,116,105,118,101,11,27,248,22,150,7,6,4,4,80, +65,84,72,251,2,52,198,199,200,28,196,27,249,80,158,42,46,199,9,28,249, +22,138,8,247,22,152,7,2,21,249,22,63,248,22,168,12,5,1,46,194,192, +9,27,248,22,184,12,195,28,248,22,171,12,193,250,2,53,198,199,195,11,250, +80,158,37,47,196,197,11,250,80,158,37,47,196,11,11,87,94,249,22,189,5, +247,22,166,4,195,248,22,140,5,249,22,151,3,34,249,22,135,3,197,198,27, +248,22,134,13,2,20,27,249,80,158,38,47,195,11,27,27,248,22,154,3,198, +28,192,192,34,27,27,248,22,154,3,200,28,192,192,34,27,249,22,183,4,197, +89,162,34,34,46,9,224,4,3,33,59,27,248,22,170,4,194,87,94,248,22, 134,4,21,94,2,17,2,29,248,80,159,41,53,35,193,159,34,20,102,159,34, 16,1,20,24,65,98,101,103,105,110,16,0,83,158,40,20,99,134,67,35,37, 117,116,105,108,115,2,1,11,10,10,10,10,10,41,80,158,34,34,20,102,159, @@ -288,7 +292,7 @@ 16,2,32,0,89,162,34,35,42,2,12,222,33,46,80,159,34,44,35,83,158, 34,16,2,83,158,37,20,96,95,2,13,89,162,34,34,41,9,223,0,33,47, 89,162,34,35,51,9,223,0,33,48,80,159,34,45,35,83,158,34,16,2,27, -248,22,140,13,248,22,144,7,27,28,249,22,137,8,247,22,152,7,2,21,6, +248,22,141,13,248,22,144,7,27,28,249,22,138,8,247,22,152,7,2,21,6, 1,1,59,6,1,1,58,250,22,181,6,6,14,14,40,91,94,126,97,93,42, 41,126,97,40,46,42,41,195,195,89,162,34,36,46,2,14,223,0,33,51,80, 159,34,46,35,83,158,34,16,2,83,158,37,20,96,96,2,15,89,162,8,36, @@ -299,160 +303,160 @@ EVAL_ONE_SIZED_STR((char *)expr, 4194); } { - static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,8,51,46,57,57,46,48,46,57,7,0,0,0,1,0,0,6,0,19, -0,34,0,48,0,62,0,76,0,0,0,253,0,0,0,65,113,117,111,116,101, -29,94,2,1,67,35,37,117,116,105,108,115,11,29,94,2,1,69,35,37,110, -101,116,119,111,114,107,11,29,94,2,1,68,35,37,112,97,114,97,109,122,11, -29,94,2,1,68,35,37,101,120,112,111,98,115,11,29,94,2,1,68,35,37, -107,101,114,110,101,108,11,159,34,20,102,159,34,16,1,20,24,65,98,101,103, -105,110,16,0,83,158,40,20,99,134,69,35,37,98,117,105,108,116,105,110,29, -11,11,10,10,18,94,11,97,10,34,11,97,159,2,2,34,34,159,2,3,34, -34,159,2,4,34,34,159,2,5,34,34,159,2,6,34,34,16,0,18,94,11, -95,35,11,16,0,10,18,94,11,95,8,240,48,117,0,0,11,16,0,34,80, -158,34,34,20,102,159,34,16,0,16,0,11,11,16,0,34,11,11,11,16,0, -16,0,16,0,34,34,11,11,16,0,16,0,16,0,34,34,11,11,16,0,16, -0,16,0,34,34,16,0,16,0,98,2,6,2,5,29,94,2,1,69,35,37, -102,111,114,101,105,103,110,11,2,4,2,3,2,2,9,9,0}; - EVAL_ONE_SIZED_STR((char *)expr, 289); + static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,51,46,57,57,46,48,46,49,49,7,0,0,0,1,0,0,6,0, +19,0,34,0,48,0,62,0,76,0,0,0,253,0,0,0,65,113,117,111,116, +101,29,94,2,1,67,35,37,117,116,105,108,115,11,29,94,2,1,69,35,37, +110,101,116,119,111,114,107,11,29,94,2,1,68,35,37,112,97,114,97,109,122, +11,29,94,2,1,68,35,37,101,120,112,111,98,115,11,29,94,2,1,68,35, +37,107,101,114,110,101,108,11,159,34,20,102,159,34,16,1,20,24,65,98,101, +103,105,110,16,0,83,158,40,20,99,134,69,35,37,98,117,105,108,116,105,110, +29,11,11,10,10,18,94,11,97,10,34,11,97,159,2,2,34,34,159,2,3, +34,34,159,2,4,34,34,159,2,5,34,34,159,2,6,34,34,16,0,18,94, +11,95,35,11,16,0,10,18,94,11,95,8,240,48,117,0,0,11,16,0,34, +80,158,34,34,20,102,159,34,16,0,16,0,11,11,16,0,34,11,11,11,16, +0,16,0,16,0,34,34,11,11,16,0,16,0,16,0,34,34,11,11,16,0, +16,0,16,0,34,34,16,0,16,0,98,2,6,2,5,29,94,2,1,69,35, +37,102,111,114,101,105,103,110,11,2,4,2,3,2,2,9,9,0}; + EVAL_ONE_SIZED_STR((char *)expr, 290); } { - static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,8,51,46,57,57,46,48,46,57,52,0,0,0,1,0,0,3,0,14, -0,41,0,47,0,60,0,74,0,96,0,122,0,134,0,152,0,172,0,184,0, -200,0,223,0,3,1,8,1,13,1,18,1,23,1,54,1,58,1,66,1,74, -1,82,1,163,1,199,1,216,1,245,1,17,2,47,2,57,2,87,2,97,2, -104,2,178,3,190,3,209,3,33,4,45,4,173,4,185,4,30,5,36,5,50, -5,77,5,148,5,150,5,203,5,93,10,152,10,184,10,0,0,119,13,0,0, -29,11,11,70,100,108,108,45,115,117,102,102,105,120,1,25,100,101,102,97,117, -108,116,45,108,111,97,100,47,117,115,101,45,99,111,109,112,105,108,101,100,65, -113,117,111,116,101,29,94,2,4,67,35,37,117,116,105,108,115,11,29,94,2, -4,68,35,37,112,97,114,97,109,122,11,1,20,100,101,102,97,117,108,116,45, -114,101,97,100,101,114,45,103,117,97,114,100,1,24,45,109,111,100,117,108,101, -45,104,97,115,104,45,116,97,98,108,101,45,116,97,98,108,101,71,45,112,97, -116,104,45,99,97,99,104,101,77,45,108,111,97,100,105,110,103,45,102,105,108, -101,110,97,109,101,79,45,108,111,97,100,105,110,103,45,112,114,111,109,112,116, -45,116,97,103,71,45,112,114,101,118,45,114,101,108,116,111,75,45,112,114,101, -118,45,114,101,108,116,111,45,100,105,114,1,21,115,112,108,105,116,45,114,101, -108,97,116,105,118,101,45,115,116,114,105,110,103,1,34,109,97,107,101,45,115, -116,97,110,100,97,114,100,45,109,111,100,117,108,101,45,110,97,109,101,45,114, -101,115,111,108,118,101,114,64,98,111,111,116,64,115,97,109,101,64,119,101,97, -107,64,108,111,111,112,1,29,115,116,97,110,100,97,114,100,45,109,111,100,117, -108,101,45,110,97,109,101,45,114,101,115,111,108,118,101,114,63,108,105,98,67, -105,103,110,111,114,101,100,249,22,14,195,80,158,36,44,249,80,159,36,47,35, -195,10,27,28,194,28,249,22,137,8,196,80,158,37,45,80,158,35,46,27,248, -22,149,4,196,28,248,22,158,12,193,91,159,37,11,90,161,37,34,11,248,22, -179,12,196,87,95,83,160,36,11,80,158,39,45,198,83,160,36,11,80,158,39, -46,192,192,11,11,28,192,192,27,247,22,185,5,28,192,192,247,22,134,13,20, -14,159,80,158,34,38,250,80,158,37,39,249,22,27,11,80,158,39,38,22,185, -5,28,248,22,158,12,197,196,247,22,134,13,247,194,250,22,176,12,196,198,249, -80,158,41,37,197,5,3,46,122,111,252,22,176,12,198,200,6,6,6,110,97, -116,105,118,101,247,22,153,7,249,80,158,43,37,199,80,158,43,34,27,193,27, -250,22,129,13,196,11,32,0,89,162,8,44,34,39,9,222,11,28,192,249,22, -63,195,194,11,27,248,194,195,27,250,22,129,13,196,11,32,0,89,162,8,44, -34,39,9,222,11,28,192,249,22,63,195,194,11,249,247,22,139,13,248,22,64, -195,195,27,248,194,195,27,250,22,129,13,196,11,32,0,89,162,8,44,34,39, -9,222,11,28,192,249,22,63,195,194,11,249,247,22,183,5,248,22,64,195,195, -249,247,22,183,5,194,195,87,94,28,248,80,158,35,36,194,12,250,22,167,8, -77,108,111,97,100,47,117,115,101,45,99,111,109,112,105,108,101,100,6,25,25, -112,97,116,104,32,111,114,32,118,97,108,105,100,45,112,97,116,104,32,115,116, -114,105,110,103,196,91,159,40,11,90,161,35,34,11,28,248,22,182,12,200,199, -27,247,22,185,5,28,192,249,22,183,12,202,194,200,90,161,37,35,11,248,22, -179,12,193,90,161,35,38,11,28,249,22,137,8,195,68,114,101,108,97,116,105, -118,101,2,17,193,90,161,35,39,11,247,22,136,13,27,89,162,34,35,48,62, -122,111,225,7,5,3,33,27,27,89,162,34,35,50,9,225,8,6,4,33,28, -27,249,22,5,89,162,34,35,46,9,223,5,33,29,202,27,28,194,27,249,22, -5,89,162,34,35,46,9,223,5,33,30,204,27,28,195,11,193,28,192,192,28, -193,28,195,28,249,22,147,3,248,22,65,196,248,22,65,198,193,11,11,11,11, -28,192,249,80,159,46,53,35,202,89,162,34,34,44,9,224,14,2,33,31,27, -28,196,27,249,22,5,89,162,34,35,46,9,223,7,33,32,205,27,28,196,11, -193,28,192,192,28,193,28,196,28,249,22,147,3,248,22,65,196,248,22,65,199, -193,11,11,11,11,28,192,249,80,159,47,53,35,203,89,162,34,34,44,9,224, -15,2,33,33,249,80,159,47,53,35,203,89,162,34,34,43,9,224,15,7,33, -34,32,36,89,162,34,35,53,2,19,222,33,38,0,17,35,114,120,34,94,40, -46,42,63,41,47,40,46,42,41,36,34,27,249,22,144,13,2,37,195,28,192, -249,22,63,248,22,88,195,27,248,22,97,196,27,249,22,144,13,2,37,195,28, -192,249,22,63,248,22,88,195,27,248,22,97,196,27,249,22,144,13,2,37,195, -28,192,249,22,63,248,22,88,195,248,2,36,248,22,97,196,248,22,73,194,248, -22,73,194,248,22,73,194,32,39,89,162,34,35,53,2,19,222,33,40,28,248, -22,71,248,22,65,194,249,22,7,9,248,22,64,195,91,159,36,11,90,161,36, -34,11,27,248,22,65,196,28,248,22,71,248,22,65,194,249,22,7,9,248,22, -64,195,91,159,36,11,90,161,36,34,11,27,248,22,65,196,28,248,22,71,248, -22,65,194,249,22,7,9,248,22,64,195,91,159,36,11,90,161,36,34,11,248, -2,39,248,22,65,196,249,22,7,249,22,63,248,22,64,199,196,195,249,22,7, -249,22,63,248,22,64,199,196,195,249,22,7,249,22,63,248,22,64,199,196,195, -27,248,2,36,194,28,194,192,248,2,39,193,87,95,28,248,22,147,4,195,12, -250,22,167,8,2,20,6,20,20,114,101,115,111,108,118,101,100,45,109,111,100, -117,108,101,45,112,97,116,104,197,28,207,248,208,195,12,27,27,250,22,126,80, -158,40,41,248,22,162,13,247,22,146,11,11,28,192,192,27,247,22,120,87,94, -250,22,125,80,158,41,41,248,22,162,13,247,22,146,11,195,192,250,22,125,195, -198,66,97,116,116,97,99,104,251,211,197,198,199,10,28,192,250,22,166,8,11, -196,195,248,22,164,8,194,28,249,22,139,6,194,6,1,1,46,2,17,28,249, -22,139,6,194,6,2,2,46,46,62,117,112,192,28,249,22,139,8,248,22,65, -199,196,28,249,22,137,8,248,22,64,199,195,251,22,164,8,2,20,6,26,26, -99,121,99,108,101,32,105,110,32,108,111,97,100,105,110,103,32,97,116,32,126, -101,58,32,126,101,199,249,22,2,22,65,248,22,78,249,22,63,205,201,12,12, -247,192,20,14,159,80,158,38,43,249,22,63,247,22,146,11,196,20,14,159,80, -158,38,38,250,80,158,41,39,249,22,27,11,80,158,43,38,22,131,4,195,249, -247,22,184,5,197,248,22,52,248,22,162,12,197,87,94,28,28,248,22,158,12, -196,10,248,22,152,4,196,12,28,197,250,22,166,8,11,6,15,15,98,97,100, -32,109,111,100,117,108,101,32,112,97,116,104,200,250,22,167,8,2,20,6,19, -19,109,111,100,117,108,101,45,112,97,116,104,32,111,114,32,112,97,116,104,198, -28,28,248,22,61,196,249,22,137,8,248,22,64,198,2,4,11,248,22,148,4, -248,22,88,197,28,28,248,22,61,196,249,22,137,8,248,22,64,198,66,112,108, -97,110,101,116,11,87,94,28,207,12,20,14,159,80,158,36,38,250,80,158,39, -39,249,22,27,11,80,158,41,38,22,146,11,196,90,161,35,34,10,249,22,132, -4,21,94,2,21,6,18,18,112,108,97,110,101,116,47,114,101,115,111,108,118, -101,114,46,115,115,1,27,112,108,97,110,101,116,45,109,111,100,117,108,101,45, -110,97,109,101,45,114,101,115,111,108,118,101,114,12,251,211,199,200,201,202,27, -89,162,34,35,44,79,115,104,111,119,45,99,111,108,108,101,99,116,105,111,110, -45,101,114,114,223,6,33,44,27,28,248,22,51,198,27,250,22,126,80,158,42, -42,249,22,63,203,247,22,135,13,11,28,192,192,91,159,36,11,90,161,36,34, -11,249,80,159,43,47,35,248,22,54,203,11,27,251,80,158,46,49,2,20,201, -28,248,22,71,198,198,248,22,64,198,28,248,22,71,198,9,248,22,65,198,249, -22,176,12,194,28,248,22,71,196,6,7,7,109,97,105,110,46,115,115,249,22, -156,6,198,6,3,3,46,115,115,28,248,22,133,6,198,27,248,80,159,40,54, -35,200,27,250,22,126,80,158,43,42,249,22,63,204,198,11,28,192,192,91,159, -36,11,90,161,36,34,11,249,80,159,44,47,35,203,11,250,22,1,22,176,12, -198,249,22,77,249,22,2,32,0,89,162,8,36,35,42,9,222,33,45,199,248, -22,73,199,28,248,22,158,12,198,28,248,22,181,12,198,197,248,22,73,6,26, -26,32,40,97,32,112,97,116,104,32,109,117,115,116,32,98,101,32,97,98,115, -111,108,117,116,101,41,28,249,22,137,8,248,22,64,200,2,21,27,250,22,126, -80,158,42,42,249,22,63,203,247,22,135,13,11,28,192,192,91,159,37,11,90, -161,36,34,11,249,80,159,44,47,35,248,22,88,204,11,90,161,35,36,11,28, -248,22,71,248,22,90,203,28,248,22,71,193,249,22,146,13,0,8,35,114,120, -34,91,46,93,34,195,11,10,27,27,28,196,249,22,77,28,248,22,71,248,22, -90,23,15,21,93,6,5,5,109,122,108,105,98,249,22,1,22,77,249,22,2, -80,159,50,55,35,248,22,90,23,18,196,28,248,22,71,195,248,22,73,196,194, -251,80,158,48,49,2,20,203,248,22,64,197,248,22,65,197,249,22,176,12,194, -28,197,196,28,248,22,71,196,6,7,7,109,97,105,110,46,115,115,28,249,22, -146,13,0,8,35,114,120,34,91,46,93,34,198,196,249,22,156,6,198,6,3, -3,46,115,115,28,249,22,137,8,248,22,64,200,64,102,105,108,101,249,22,183, -12,248,22,88,200,248,80,159,41,54,35,201,12,87,94,28,28,248,22,158,12, -193,10,248,22,155,7,193,12,28,199,250,22,166,8,67,114,101,113,117,105,114, -101,249,22,181,6,6,17,17,98,97,100,32,109,111,100,117,108,101,32,112,97, -116,104,126,97,28,197,248,22,64,198,6,0,0,202,250,22,167,8,2,20,249, -22,181,6,6,13,13,109,111,100,117,108,101,32,112,97,116,104,126,97,28,197, -248,22,64,198,6,0,0,200,27,28,248,22,155,7,194,249,22,160,7,195,34, -249,22,185,12,248,22,186,12,196,11,27,28,248,22,155,7,195,249,22,160,7, -196,35,248,80,158,41,50,194,91,159,37,11,90,161,37,34,11,28,248,22,155, -7,198,250,22,7,2,22,249,22,160,7,202,36,2,22,248,22,179,12,197,27, -28,248,22,155,7,199,249,22,160,7,200,37,249,80,158,46,51,196,5,0,27, -28,248,22,155,7,200,249,22,160,7,201,38,248,22,148,4,199,27,27,250,22, -126,80,158,50,41,248,22,162,13,247,22,146,11,11,28,192,192,27,247,22,120, -87,94,250,22,125,80,158,51,41,248,22,162,13,247,22,146,11,195,192,87,95, -28,23,16,27,250,22,126,196,197,11,28,192,12,87,95,27,27,28,248,22,17, -80,158,50,44,80,158,49,44,247,22,19,250,22,25,248,22,23,196,80,158,52, -43,195,27,247,22,146,11,249,22,3,89,162,34,35,53,9,226,12,11,2,3, -33,46,195,248,28,248,22,17,80,158,49,44,32,0,89,162,34,35,40,9,222, -33,47,80,159,48,56,35,89,162,34,34,49,9,227,14,9,8,4,3,33,48, -250,22,125,196,197,10,12,28,28,248,22,155,7,201,11,27,248,22,133,6,23, -15,28,192,192,28,248,22,61,23,15,249,22,137,8,248,22,64,23,17,2,21, -11,250,22,125,80,158,49,42,28,248,22,133,6,23,17,249,22,63,23,18,248, -80,159,52,54,35,23,20,249,22,63,23,18,247,22,135,13,252,22,157,7,23, -15,206,204,202,201,12,193,91,159,36,10,90,161,35,34,10,11,90,161,35,35, -10,83,158,37,20,96,96,2,20,89,162,8,36,35,49,9,224,2,0,33,42, + static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,51,46,57,57,46,48,46,49,49,52,0,0,0,1,0,0,3,0, +14,0,41,0,47,0,60,0,74,0,96,0,122,0,134,0,152,0,172,0,184, +0,200,0,223,0,3,1,8,1,13,1,18,1,23,1,54,1,58,1,66,1, +74,1,82,1,163,1,199,1,216,1,245,1,17,2,47,2,57,2,87,2,97, +2,104,2,178,3,190,3,209,3,33,4,45,4,173,4,185,4,30,5,36,5, +50,5,77,5,148,5,150,5,203,5,93,10,151,10,183,10,0,0,118,13,0, +0,29,11,11,70,100,108,108,45,115,117,102,102,105,120,1,25,100,101,102,97, +117,108,116,45,108,111,97,100,47,117,115,101,45,99,111,109,112,105,108,101,100, +65,113,117,111,116,101,29,94,2,4,67,35,37,117,116,105,108,115,11,29,94, +2,4,68,35,37,112,97,114,97,109,122,11,1,20,100,101,102,97,117,108,116, +45,114,101,97,100,101,114,45,103,117,97,114,100,1,24,45,109,111,100,117,108, +101,45,104,97,115,104,45,116,97,98,108,101,45,116,97,98,108,101,71,45,112, +97,116,104,45,99,97,99,104,101,77,45,108,111,97,100,105,110,103,45,102,105, +108,101,110,97,109,101,79,45,108,111,97,100,105,110,103,45,112,114,111,109,112, +116,45,116,97,103,71,45,112,114,101,118,45,114,101,108,116,111,75,45,112,114, +101,118,45,114,101,108,116,111,45,100,105,114,1,21,115,112,108,105,116,45,114, +101,108,97,116,105,118,101,45,115,116,114,105,110,103,1,34,109,97,107,101,45, +115,116,97,110,100,97,114,100,45,109,111,100,117,108,101,45,110,97,109,101,45, +114,101,115,111,108,118,101,114,64,98,111,111,116,64,115,97,109,101,64,119,101, +97,107,64,108,111,111,112,1,29,115,116,97,110,100,97,114,100,45,109,111,100, +117,108,101,45,110,97,109,101,45,114,101,115,111,108,118,101,114,63,108,105,98, +67,105,103,110,111,114,101,100,249,22,14,195,80,158,36,44,249,80,159,36,47, +35,195,10,27,28,194,28,249,22,138,8,196,80,158,37,45,80,158,35,46,27, +248,22,149,4,196,28,248,22,159,12,193,91,159,37,11,90,161,37,34,11,248, +22,180,12,196,87,95,83,160,36,11,80,158,39,45,198,83,160,36,11,80,158, +39,46,192,192,11,11,28,192,192,27,247,22,185,5,28,192,192,247,22,135,13, +20,14,159,80,158,34,38,250,80,158,37,39,249,22,27,11,80,158,39,38,22, +185,5,28,248,22,159,12,197,196,247,22,135,13,247,194,250,22,177,12,196,198, +249,80,158,41,37,197,5,3,46,122,111,252,22,177,12,198,200,6,6,6,110, +97,116,105,118,101,247,22,153,7,249,80,158,43,37,199,80,158,43,34,27,193, +27,250,22,130,13,196,11,32,0,89,162,8,36,34,39,9,222,11,28,192,249, +22,63,195,194,11,27,248,194,195,27,250,22,130,13,196,11,32,0,89,162,8, +36,34,39,9,222,11,28,192,249,22,63,195,194,11,249,247,22,140,13,248,22, +64,195,195,27,248,194,195,27,250,22,130,13,196,11,32,0,89,162,8,36,34, +39,9,222,11,28,192,249,22,63,195,194,11,249,247,22,183,5,248,22,64,195, +195,249,247,22,183,5,194,195,87,94,28,248,80,158,35,36,194,12,250,22,168, +8,77,108,111,97,100,47,117,115,101,45,99,111,109,112,105,108,101,100,6,25, +25,112,97,116,104,32,111,114,32,118,97,108,105,100,45,112,97,116,104,32,115, +116,114,105,110,103,196,91,159,40,11,90,161,35,34,11,28,248,22,183,12,200, +199,27,247,22,185,5,28,192,249,22,184,12,202,194,200,90,161,37,35,11,248, +22,180,12,193,90,161,35,38,11,28,249,22,138,8,195,68,114,101,108,97,116, +105,118,101,2,17,193,90,161,35,39,11,247,22,137,13,27,89,162,34,35,48, +62,122,111,225,7,5,3,33,27,27,89,162,34,35,50,9,225,8,6,4,33, +28,27,249,22,5,89,162,34,35,46,9,223,5,33,29,202,27,28,194,27,249, +22,5,89,162,34,35,46,9,223,5,33,30,204,27,28,195,11,193,28,192,192, +28,193,28,195,28,249,22,147,3,248,22,65,196,248,22,65,198,193,11,11,11, +11,28,192,249,80,159,46,53,35,202,89,162,34,34,44,9,224,14,2,33,31, +27,28,196,27,249,22,5,89,162,34,35,46,9,223,7,33,32,205,27,28,196, +11,193,28,192,192,28,193,28,196,28,249,22,147,3,248,22,65,196,248,22,65, +199,193,11,11,11,11,28,192,249,80,159,47,53,35,203,89,162,34,34,44,9, +224,15,2,33,33,249,80,159,47,53,35,203,89,162,34,34,43,9,224,15,7, +33,34,32,36,89,162,34,35,53,2,19,222,33,38,0,17,35,114,120,34,94, +40,46,42,63,41,47,40,46,42,41,36,34,27,249,22,145,13,2,37,195,28, +192,249,22,63,248,22,88,195,27,248,22,97,196,27,249,22,145,13,2,37,195, +28,192,249,22,63,248,22,88,195,27,248,22,97,196,27,249,22,145,13,2,37, +195,28,192,249,22,63,248,22,88,195,248,2,36,248,22,97,196,248,22,73,194, +248,22,73,194,248,22,73,194,32,39,89,162,34,35,53,2,19,222,33,40,28, +248,22,71,248,22,65,194,249,22,7,9,248,22,64,195,91,159,36,11,90,161, +36,34,11,27,248,22,65,196,28,248,22,71,248,22,65,194,249,22,7,9,248, +22,64,195,91,159,36,11,90,161,36,34,11,27,248,22,65,196,28,248,22,71, +248,22,65,194,249,22,7,9,248,22,64,195,91,159,36,11,90,161,36,34,11, +248,2,39,248,22,65,196,249,22,7,249,22,63,248,22,64,199,196,195,249,22, +7,249,22,63,248,22,64,199,196,195,249,22,7,249,22,63,248,22,64,199,196, +195,27,248,2,36,194,28,194,192,248,2,39,193,87,95,28,248,22,147,4,195, +12,250,22,168,8,2,20,6,20,20,114,101,115,111,108,118,101,100,45,109,111, +100,117,108,101,45,112,97,116,104,197,28,207,248,208,195,12,27,27,250,22,126, +80,158,40,41,248,22,163,13,247,22,147,11,11,28,192,192,27,247,22,120,87, +94,250,22,125,80,158,41,41,248,22,163,13,247,22,147,11,195,192,250,22,125, +195,198,66,97,116,116,97,99,104,251,211,197,198,199,10,28,192,250,22,167,8, +11,196,195,248,22,165,8,194,28,249,22,139,6,194,6,1,1,46,2,17,28, +249,22,139,6,194,6,2,2,46,46,62,117,112,192,28,249,22,140,8,248,22, +65,199,196,28,249,22,138,8,248,22,64,199,195,251,22,165,8,2,20,6,26, +26,99,121,99,108,101,32,105,110,32,108,111,97,100,105,110,103,32,97,116,32, +126,101,58,32,126,101,199,249,22,2,22,65,248,22,78,249,22,63,205,201,12, +12,247,192,20,14,159,80,158,38,43,249,22,63,247,22,147,11,196,20,14,159, +80,158,38,38,250,80,158,41,39,249,22,27,11,80,158,43,38,22,131,4,195, +249,247,22,184,5,197,248,22,52,248,22,163,12,197,87,94,28,28,248,22,159, +12,196,10,248,22,152,4,196,12,28,197,250,22,167,8,11,6,15,15,98,97, +100,32,109,111,100,117,108,101,32,112,97,116,104,200,250,22,168,8,2,20,6, +19,19,109,111,100,117,108,101,45,112,97,116,104,32,111,114,32,112,97,116,104, +198,28,28,248,22,61,196,249,22,138,8,248,22,64,198,2,4,11,248,22,148, +4,248,22,88,197,28,28,248,22,61,196,249,22,138,8,248,22,64,198,66,112, +108,97,110,101,116,11,87,94,28,207,12,20,14,159,80,158,36,38,250,80,158, +39,39,249,22,27,11,80,158,41,38,22,147,11,196,90,161,35,34,10,249,22, +132,4,21,94,2,21,6,18,18,112,108,97,110,101,116,47,114,101,115,111,108, +118,101,114,46,115,115,1,27,112,108,97,110,101,116,45,109,111,100,117,108,101, +45,110,97,109,101,45,114,101,115,111,108,118,101,114,12,251,211,199,200,201,202, +27,89,162,34,35,44,79,115,104,111,119,45,99,111,108,108,101,99,116,105,111, +110,45,101,114,114,223,6,33,44,27,28,248,22,51,198,27,250,22,126,80,158, +42,42,249,22,63,203,247,22,136,13,11,28,192,192,91,159,36,11,90,161,36, +34,11,249,80,159,43,47,35,248,22,54,203,11,27,251,80,158,46,49,2,20, +201,28,248,22,71,198,198,248,22,64,198,28,248,22,71,198,9,248,22,65,198, +249,22,177,12,194,28,248,22,71,196,6,7,7,109,97,105,110,46,115,115,249, +22,156,6,198,6,3,3,46,115,115,28,248,22,133,6,198,27,248,80,159,40, +54,35,200,27,250,22,126,80,158,43,42,249,22,63,204,198,11,28,192,192,91, +159,36,11,90,161,36,34,11,249,80,159,44,47,35,203,11,250,22,1,22,177, +12,198,249,22,77,249,22,2,32,0,89,162,8,36,35,42,9,222,33,45,199, +248,22,73,199,28,248,22,159,12,198,28,248,22,182,12,198,197,248,22,73,6, +26,26,32,40,97,32,112,97,116,104,32,109,117,115,116,32,98,101,32,97,98, +115,111,108,117,116,101,41,28,249,22,138,8,248,22,64,200,2,21,27,250,22, +126,80,158,42,42,249,22,63,203,247,22,136,13,11,28,192,192,91,159,37,11, +90,161,36,34,11,249,80,159,44,47,35,248,22,88,204,11,90,161,35,36,11, +28,248,22,71,248,22,90,203,28,248,22,71,193,249,22,147,13,0,8,35,114, +120,34,91,46,93,34,195,11,10,27,27,28,196,249,22,77,28,248,22,71,248, +22,90,23,15,21,93,6,5,5,109,122,108,105,98,249,22,1,22,77,249,22, +2,80,159,50,55,35,248,22,90,23,18,196,28,248,22,71,195,248,22,73,196, +194,251,80,158,48,49,2,20,203,248,22,64,197,248,22,65,197,249,22,177,12, +194,28,197,196,28,248,22,71,196,6,7,7,109,97,105,110,46,115,115,28,249, +22,147,13,0,8,35,114,120,34,91,46,93,34,198,196,249,22,156,6,198,6, +3,3,46,115,115,28,249,22,138,8,248,22,64,200,64,102,105,108,101,249,22, +184,12,248,22,88,200,248,80,159,41,54,35,201,12,87,94,28,28,248,22,159, +12,193,10,248,22,155,7,193,12,28,199,250,22,167,8,67,114,101,113,117,105, +114,101,249,22,181,6,6,17,17,98,97,100,32,109,111,100,117,108,101,32,112, +97,116,104,126,97,28,197,248,22,64,198,6,0,0,202,250,22,168,8,2,20, +249,22,181,6,6,13,13,109,111,100,117,108,101,32,112,97,116,104,126,97,28, +197,248,22,64,198,6,0,0,200,27,28,248,22,155,7,194,249,22,160,7,195, +34,249,22,186,12,248,22,187,12,196,11,27,28,248,22,155,7,195,249,22,160, +7,196,35,248,80,158,41,50,194,91,159,37,11,90,161,37,34,11,28,248,22, +155,7,198,250,22,7,2,22,249,22,160,7,202,36,2,22,248,22,180,12,197, +27,28,248,22,155,7,199,249,22,160,7,200,37,249,80,158,46,51,196,5,0, +27,28,248,22,155,7,200,249,22,160,7,201,38,248,22,148,4,199,27,27,250, +22,126,80,158,50,41,248,22,163,13,247,22,147,11,11,28,192,192,27,247,22, +120,87,94,250,22,125,80,158,51,41,248,22,163,13,247,22,147,11,195,192,87, +95,28,23,16,27,250,22,126,196,197,11,28,192,12,87,95,27,27,28,248,22, +17,80,158,50,44,80,158,49,44,247,22,19,250,22,25,248,22,23,196,80,158, +52,43,195,27,247,22,147,11,249,22,3,89,162,34,35,53,9,226,12,11,2, +3,33,46,195,248,28,248,22,17,80,158,49,44,32,0,89,162,34,35,40,9, +222,33,47,80,159,48,56,35,89,162,34,34,49,9,227,14,9,8,4,3,33, +48,250,22,125,196,197,10,12,28,28,248,22,155,7,201,11,27,248,22,133,6, +23,15,28,192,192,28,248,22,61,23,15,249,22,138,8,248,22,64,23,17,2, +21,11,250,22,125,80,158,49,42,28,248,22,133,6,23,17,249,22,63,23,18, +248,80,159,52,54,35,23,20,249,22,63,23,18,247,22,136,13,252,22,157,7, +23,15,206,204,202,201,12,193,91,159,36,10,90,161,35,34,10,11,90,161,35, +35,10,83,158,37,20,96,96,2,20,89,162,34,35,49,9,224,2,0,33,42, 89,162,34,37,47,9,223,1,33,43,89,162,34,38,8,30,9,225,2,3,0, -33,49,208,87,95,248,22,130,4,248,80,158,36,48,247,22,146,11,248,22,184, -5,80,158,35,35,248,22,132,12,80,159,35,40,35,159,34,20,102,159,34,16, +33,49,208,87,95,248,22,130,4,248,80,158,36,48,247,22,147,11,248,22,184, +5,80,158,35,35,248,22,133,12,80,159,35,40,35,159,34,20,102,159,34,16, 1,20,24,65,98,101,103,105,110,16,0,83,158,40,20,99,134,66,35,37,98, 111,111,116,2,1,11,10,10,10,10,10,36,80,158,34,34,20,102,159,38,16, 19,30,2,1,2,2,193,30,2,1,2,3,193,30,2,5,72,112,97,116,104, diff --git a/src/mzscheme/src/env.c b/src/mzscheme/src/env.c index 0824d225cd..f60a82febb 100644 --- a/src/mzscheme/src/env.c +++ b/src/mzscheme/src/env.c @@ -54,7 +54,7 @@ int scheme_get_allow_set_undefined() { return scheme_allow_set_undefined; } int scheme_starting_up; -Scheme_Object *scheme_local[MAX_CONST_LOCAL_POS][2]; +Scheme_Object *scheme_local[MAX_CONST_LOCAL_POS][2][3]; #define MAX_CONST_TOPLEVEL_DEPTH 16 #define MAX_CONST_TOPLEVEL_POS 16 @@ -256,30 +256,33 @@ Scheme_Env *scheme_basic_env() { - int i, k; + int i, k, cor; #ifndef USE_TAGGED_ALLOCATION GC_CAN_IGNORE Scheme_Local *all; - all = (Scheme_Local *)scheme_malloc_eternal(sizeof(Scheme_Local) * 2 * MAX_CONST_LOCAL_POS); + all = (Scheme_Local *)scheme_malloc_eternal(sizeof(Scheme_Local) * 3 * 2 * MAX_CONST_LOCAL_POS); # ifdef MEMORY_COUNTING_ON - scheme_misc_count += sizeof(Scheme_Local) * 2 * MAX_CONST_LOCAL_POS; + scheme_misc_count += sizeof(Scheme_Local) * 3 * 2 * MAX_CONST_LOCAL_POS; # endif #endif for (i = 0; i < MAX_CONST_LOCAL_POS; i++) { for (k = 0; k < 2; k++) { - Scheme_Object *v; - + for (cor = 0; cor < 3; cor++) { + Scheme_Object *v; + #ifndef USE_TAGGED_ALLOCATION - v = (Scheme_Object *)(all++); + v = (Scheme_Object *)(all++); #else - v = (Scheme_Object *)scheme_malloc_eternal_tagged(sizeof(Scheme_Local)); + v = (Scheme_Object *)scheme_malloc_eternal_tagged(sizeof(Scheme_Local)); #endif - v->type = k + scheme_local_type; - SCHEME_LOCAL_POS(v) = i; - - scheme_local[i][k] = v; + v->type = k + scheme_local_type; + SCHEME_LOCAL_POS(v) = i; + SCHEME_LOCAL_FLAGS(v) = cor; + + scheme_local[i][k][cor] = v; + } } } } @@ -1541,7 +1544,7 @@ Scheme_Object *scheme_register_stx_in_prefix(Scheme_Object *var, Scheme_Comp_Env if (rec && rec[drec].dont_mark_local_use) { /* Make up anything; it's going to be ignored. */ l = (Scheme_Local *)scheme_malloc_atomic_tagged(sizeof(Scheme_Local)); - l->so.type = scheme_compiled_quote_syntax_type; + l->iso.so.type = scheme_compiled_quote_syntax_type; l->position = 0; return (Scheme_Object *)l; @@ -1556,7 +1559,7 @@ Scheme_Object *scheme_register_stx_in_prefix(Scheme_Object *var, Scheme_Comp_Env pos = cp->num_stxes; l = (Scheme_Local *)scheme_malloc_atomic_tagged(sizeof(Scheme_Local)); - l->so.type = scheme_compiled_quote_syntax_type; + l->iso.so.type = scheme_compiled_quote_syntax_type; l->position = pos; cp->num_stxes++; @@ -1582,23 +1585,40 @@ static Scheme_Object *alloc_local(short type, int pos) return (Scheme_Object *)v; } -Scheme_Object *scheme_make_local(Scheme_Type type, int pos) +Scheme_Object *scheme_make_local(Scheme_Type type, int pos, int flags) { int k; - Scheme_Object *v; + Scheme_Object *v, *key; k = type - scheme_local_type; - - if (pos < MAX_CONST_LOCAL_POS) { - if (pos >= 0) - return scheme_local[pos][k]; + + /* Helper for reading bytecode: make sure flags is a valid value */ + switch (flags) { + case 0: + break; + case SCHEME_LOCAL_CLEAR_ON_READ: + break; + default: + case SCHEME_LOCAL_OTHER_CLEARS: + flags = SCHEME_LOCAL_OTHER_CLEARS; + break; } - v = scheme_hash_get(locals_ht[k], scheme_make_integer(pos)); + if (pos < MAX_CONST_LOCAL_POS) { + return scheme_local[pos][k][flags]; + } + + key = scheme_make_integer(pos); + if (flags) { + key = scheme_make_pair(scheme_make_integer(flags), key); + } + + v = scheme_hash_get(locals_ht[k], key); if (v) return v; v = alloc_local(type, pos); + SCHEME_LOCAL_FLAGS(v) = flags; if (locals_ht[k]->count > TABLE_CACHE_MAX_SIZE) { Scheme_Hash_Table *ht; @@ -1606,7 +1626,7 @@ Scheme_Object *scheme_make_local(Scheme_Type type, int pos) locals_ht[k] = ht; } - scheme_hash_set(locals_ht[k], scheme_make_integer(pos), v); + scheme_hash_set(locals_ht[k], key, v); return v; } @@ -1642,7 +1662,7 @@ static Scheme_Local *get_frame_loc(Scheme_Comp_Env *frame, COMPILE_DATA(frame)->use[i] = u; - return (Scheme_Local *)scheme_make_local(scheme_local_type, p + i); + return (Scheme_Local *)scheme_make_local(scheme_local_type, p + i, 0); } Scheme_Object *scheme_hash_module_variable(Scheme_Env *env, Scheme_Object *modidx, @@ -2384,7 +2404,7 @@ scheme_lookup_binding(Scheme_Object *find_id, Scheme_Comp_Env *env, int flags, *_lexical_binding_id = val; } if (flags & SCHEME_DONT_MARK_USE) - return scheme_make_local(scheme_local_type, 0); + return scheme_make_local(scheme_local_type, 0, 0); else return (Scheme_Object *)get_frame_loc(frame, i, j, p, flags); } @@ -2970,7 +2990,7 @@ Scheme_Object *scheme_optimize_reverse(Optimize_Info *info, int pos, int unless_ if (info->use && info->use[pos]) return NULL; - return scheme_make_local(scheme_local_type, pos + delta); + return scheme_make_local(scheme_local_type, pos + delta, 0); } int scheme_optimize_is_used(Optimize_Info *info, int pos) @@ -3063,7 +3083,7 @@ static Scheme_Object *do_optimize_info_lookup(Optimize_Info *info, int pos, int if (!n) { /* Return shifted reference to other local: */ delta += scheme_optimize_info_get_shift(info, pos); - n = scheme_make_local(scheme_local_type, pos + delta); + n = scheme_make_local(scheme_local_type, pos + delta, 0); } } return n; @@ -3386,7 +3406,8 @@ static int resolve_info_lookup(Resolve_Info *info, int pos, int *flags, Scheme_O vec = scheme_make_vector(sz + 1, NULL); for (i = 0; i < sz; i++) { loc = scheme_make_local(scheme_local_type, - posmap[i] + offset + shifted); + posmap[i] + offset + shifted, + 0); if (boxmap) { if (boxmap[i / BITS_PER_MZSHORT] & ((mzshort)1 << (i & (BITS_PER_MZSHORT - 1)))) loc = scheme_box(loc); @@ -4641,16 +4662,29 @@ static Scheme_Object *write_local(Scheme_Object *obj) return scheme_make_integer(SCHEME_LOCAL_POS(obj)); } +static Scheme_Object *do_read_local(Scheme_Type t, Scheme_Object *obj) +{ + int n, flags; + + if (SCHEME_PAIRP(obj)) { + flags = SCHEME_INT_VAL(SCHEME_CAR(obj)); + obj = SCHEME_CDR(obj); + } else + flags = 0; + + n = SCHEME_INT_VAL(obj); + + return scheme_make_local(t, n, flags); +} + static Scheme_Object *read_local(Scheme_Object *obj) { - return scheme_make_local(scheme_local_type, - SCHEME_INT_VAL(obj)); + return do_read_local(scheme_local_type, obj); } static Scheme_Object *read_local_unbox(Scheme_Object *obj) { - return scheme_make_local(scheme_local_unbox_type, - SCHEME_INT_VAL(obj)); + return do_read_local(scheme_local_unbox_type, obj); } static Scheme_Object *write_resolve_prefix(Scheme_Object *obj) @@ -4753,6 +4787,7 @@ static void register_traversers(void) GC_REG_TRAV(scheme_rt_comp_env, mark_comp_env); GC_REG_TRAV(scheme_rt_resolve_info, mark_resolve_info); GC_REG_TRAV(scheme_rt_optimize_info, mark_optimize_info); + GC_REG_TRAV(scheme_rt_sfs_info, mark_sfs_info); } END_XFORM_SKIP; diff --git a/src/mzscheme/src/eval.c b/src/mzscheme/src/eval.c index 24588f4076..fe0d9fb608 100644 --- a/src/mzscheme/src/eval.c +++ b/src/mzscheme/src/eval.c @@ -829,8 +829,10 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int resolved) vtype = SCHEME_TYPE(o); if ((vtype > _scheme_compiled_values_types_) - || (vtype == scheme_local_type) - || (vtype == scheme_local_unbox_type) + || ((vtype == scheme_local_type) + && !(SCHEME_LOCAL_FLAGS(o) & SCHEME_LOCAL_CLEAR_ON_READ)) + || ((vtype == scheme_local_unbox_type) + && !(SCHEME_LOCAL_FLAGS(o) & SCHEME_LOCAL_CLEAR_ON_READ)) || (vtype == scheme_unclosed_procedure_type) || (vtype == scheme_compiled_unclosed_procedure_type) || (vtype == scheme_case_lambda_sequence_type) @@ -1067,9 +1069,11 @@ static Scheme_Object *make_application(Scheme_Object *v) f = SCHEME_CAR(v); - if ((SCHEME_PRIMP(f) && (((Scheme_Primitive_Proc *)f)->pp.flags & SCHEME_PRIM_IS_FOLDING)) + if ((SCHEME_PRIMP(f) && ((((Scheme_Primitive_Proc *)f)->pp.flags & SCHEME_PRIM_OPT_MASK) + == SCHEME_PRIM_OPT_FOLDING)) || (SCHEME_CLSD_PRIMP(f) - && (((Scheme_Closed_Primitive_Proc *)f)->pp.flags & SCHEME_PRIM_IS_FOLDING)) + && ((((Scheme_Closed_Primitive_Proc *)f)->pp.flags & SCHEME_PRIM_OPT_MASK) + == SCHEME_PRIM_OPT_FOLDING)) || (SAME_TYPE(SCHEME_TYPE(f), scheme_closure_type) && (foldable_body(f)))) { f = try_apply(f, SCHEME_CDR(v)); @@ -1282,12 +1286,22 @@ static Scheme_Object *resolve_application(Scheme_Object *o, Resolve_Info *orig_i static Scheme_Object *resolve_application3(Scheme_Object *o, Resolve_Info *orig_info, int already_resolved_arg_count); +static void set_app2_eval_type(Scheme_App2_Rec *app) +{ + short et; + + et = scheme_get_eval_type(app->rand); + et = et << 3; + et += scheme_get_eval_type(app->rator); + + SCHEME_APPN_FLAGS(app) = et; +} + static Scheme_Object *resolve_application2(Scheme_Object *o, Resolve_Info *orig_info, int already_resolved_arg_count) { Resolve_Info *info; Scheme_App2_Rec *app; Scheme_Object *le; - short et; app = (Scheme_App2_Rec *)o; @@ -1347,16 +1361,12 @@ static Scheme_Object *resolve_application2(Scheme_Object *o, Resolve_Info *orig_ } else already_resolved_arg_count--; - et = scheme_get_eval_type(app->rand); - et = et << 3; - et += scheme_get_eval_type(app->rator); - - SCHEME_APPN_FLAGS(app) = et; - info->max_let_depth += 1; if (orig_info->max_let_depth < info->max_let_depth) orig_info->max_let_depth = info->max_let_depth; + set_app2_eval_type(app); + return (Scheme_Object *)app; } @@ -1374,12 +1384,24 @@ static int eq_testable_constant(Scheme_Object *v) return 0; } +static void set_app3_eval_type(Scheme_App3_Rec *app) +{ + short et; + + et = scheme_get_eval_type(app->rand2); + et = et << 3; + et += scheme_get_eval_type(app->rand1); + et = et << 3; + et += scheme_get_eval_type(app->rator); + + SCHEME_APPN_FLAGS(app) = et; +} + static Scheme_Object *resolve_application3(Scheme_Object *o, Resolve_Info *orig_info, int already_resolved_arg_count) { Resolve_Info *info; Scheme_App3_Rec *app; Scheme_Object *le; - short et; app = (Scheme_App3_Rec *)o; @@ -1445,13 +1467,7 @@ static Scheme_Object *resolve_application3(Scheme_Object *o, Resolve_Info *orig_ app->rator = scheme_eq_prim; } - et = scheme_get_eval_type(app->rand2); - et = et << 3; - et += scheme_get_eval_type(app->rand1); - et = et << 3; - et += scheme_get_eval_type(app->rator); - - SCHEME_APPN_FLAGS(app) = et; + set_app3_eval_type(app); info->max_let_depth += 2; if (orig_info->max_let_depth < info->max_let_depth) @@ -1828,7 +1844,8 @@ Scheme_Object *scheme_resolve_expr(Scheme_Object *expr, Resolve_Info *info) return scheme_make_local((flags & SCHEME_INFO_BOXED) ? scheme_local_unbox_type : scheme_local_type, - pos); + pos, + 0); } } case scheme_compiled_syntax_type: @@ -2094,9 +2111,11 @@ uncompile(int argc, Scheme_Object *argv[]) static Scheme_Object *try_optimize_fold(Scheme_Object *f, Scheme_Object *o, Optimize_Info *info) { if ((SCHEME_PRIMP(f) - && (((Scheme_Primitive_Proc *)f)->pp.flags & SCHEME_PRIM_IS_FOLDING)) + && ((((Scheme_Primitive_Proc *)f)->pp.flags & SCHEME_PRIM_OPT_MASK) + == SCHEME_PRIM_OPT_FOLDING)) || (SCHEME_CLSD_PRIMP(f) - && (((Scheme_Closed_Primitive_Proc *)f)->pp.flags & SCHEME_PRIM_IS_FOLDING))) { + && ((((Scheme_Closed_Primitive_Proc *)f)->pp.flags & SCHEME_PRIM_OPT_MASK) + == SCHEME_PRIM_OPT_FOLDING))) { Scheme_Object *args; switch (SCHEME_TYPE(o)) { @@ -2250,7 +2269,9 @@ Scheme_Object *optimize_for_inline(Optimize_Info *info, Scheme_Object *le, int a } if (le && SCHEME_PRIMP(le)) { - if (((Scheme_Prim_Proc_Header *)le)->flags & SCHEME_PRIM_IS_NONCM) + int opt; + opt = ((Scheme_Prim_Proc_Header *)le)->flags & SCHEME_PRIM_OPT_MASK; + if (opt > SCHEME_PRIM_OPT_NONCM) *_flags = (CLOS_PRESERVES_MARKS | CLOS_SINGLE_RESULT); } @@ -2289,7 +2310,7 @@ static Scheme_Object *check_app_let_rator(Scheme_Object *app, Scheme_Object *rat reset_rator(app, scheme_false); app = scheme_optimize_shift(app, 1, 0); - reset_rator(app, scheme_make_local(scheme_local_type, 0)); + reset_rator(app, scheme_make_local(scheme_local_type, 0, 0)); clv->body = app; @@ -2804,7 +2825,7 @@ Scheme_Object *scheme_optimize_expr(Scheme_Object *expr, Optimize_Info *info) delta = scheme_optimize_info_get_shift(info, pos); if (delta) - expr = scheme_make_local(scheme_local_type, pos + delta); + expr = scheme_make_local(scheme_local_type, pos + delta, 0); return expr; } @@ -2898,7 +2919,7 @@ Scheme_Object *scheme_optimize_clone(int dup_ok, Scheme_Object *expr, Optimize_I if (pos >= closure_depth) { expr = scheme_optimize_reverse(info, pos + delta - closure_depth, 0); if (closure_depth) - expr = scheme_make_local(scheme_local_type, SCHEME_LOCAL_POS(expr) + closure_depth); + expr = scheme_make_local(scheme_local_type, SCHEME_LOCAL_POS(expr) + closure_depth, 0); } return expr; } @@ -3088,7 +3109,7 @@ Scheme_Object *scheme_optimize_shift(Scheme_Object *expr, int delta, int after_d { int pos = SCHEME_LOCAL_POS(expr); if (pos >= after_depth) { - expr = scheme_make_local(t, SCHEME_LOCAL_POS(expr) + delta); + expr = scheme_make_local(t, SCHEME_LOCAL_POS(expr) + delta, 0); } return expr; } @@ -3224,6 +3245,821 @@ Scheme_Object *scheme_optimize_shift(Scheme_Object *expr, int delta, int after_d return NULL; } +/*========================================================================*/ +/* sfs */ +/*========================================================================*/ + +/* For debugging and measuring the worst-case cost of sfs clears: */ +#define MAX_SFS_CLEARING 0 + +#define SFS_LOG(x) /* nothing */ + +Scheme_Object *scheme_sfs(Scheme_Object *o, SFS_Info *info, int max_let_depth) +{ + int init, i; + + if (!info) { + info = scheme_new_sfs_info(max_let_depth); + } + + info->pass = 0; + info->ip = 1; + info->saved = scheme_null; + info->min_touch = -1; + info->max_touch = -1; + info->tail_pos = 1; + init = info->stackpos; + o = scheme_sfs_expr(o, info, -1); + + if (info->seqn) + scheme_signal_error("ended in the middle of an expression?"); + +# if MAX_SFS_CLEARING + info->max_nontail = info->ip; +# endif + + for (i = info->depth; i-- > init; ) { + info->max_calls[i] = info->max_nontail; + } + + { + Scheme_Object *v; + v = scheme_reverse(info->saved); + info->saved = v; + } + + info->pass = 1; + info->seqn = 0; + info->ip = 1; + info->tail_pos = 1; + info->stackpos = init; + o = scheme_sfs_expr(o, info, -1); + + return o; +} + +SFS_Info *scheme_new_sfs_info(int depth) +{ + SFS_Info *info; + int *max_used, *max_calls; + + info = MALLOC_ONE_RT(SFS_Info); + SET_REQUIRED_TAG(info->type = scheme_rt_sfs_info); + + info->depth = depth; + info->stackpos = depth; + info->tlpos = depth; + + max_used = (int *)scheme_malloc_atomic(sizeof(int) * depth); + max_calls = (int *)scheme_malloc_atomic(sizeof(int) * depth); + + memset(max_used, 0, sizeof(int) * depth); + memset(max_calls, 0, sizeof(int) * depth); + + info->max_used = max_used; + info->max_calls = max_calls; + + return info; +} + +static void scheme_sfs_save(SFS_Info *info, Scheme_Object *v) +{ + if (info->pass) + scheme_signal_error("internal error: wrong pass to save info"); + v = scheme_make_pair(v, info->saved); + info->saved = v; +} + +static Scheme_Object *scheme_sfs_next_saved(SFS_Info *info) +{ + Scheme_Object *v; + + if (!info->pass) + scheme_signal_error("internal error: wrong pass to get saved info"); + if (!SCHEME_PAIRP(info->saved)) + scheme_signal_error("internal error: no saved info"); + + v = SCHEME_CAR(info->saved); + info->saved = SCHEME_CDR(info->saved); + return v; +} + +void scheme_sfs_start_sequence(SFS_Info *info, int cnt, int last_is_tail) +{ + info->seqn += (cnt - (last_is_tail ? 1 : 0)); +} + +void scheme_sfs_push(SFS_Info *info, int cnt, int track) +{ + info->stackpos -= cnt; + + if (info->stackpos < 0) + scheme_signal_error("internal error: pushed too deep"); + + if (track) { + while (cnt--) { + scheme_sfs_used(info, cnt); + } + } +} + +void scheme_sfs_used(SFS_Info *info, int pos) +{ + if (info->pass) + return; + + pos += info->stackpos; + + if ((pos < 0) || (pos >= info->depth)) { + scheme_signal_error("internal error: stack use out of bounds"); + } + if (pos == info->tlpos) + scheme_signal_error("internal error: misuse of toplevel pointer"); + + SFS_LOG(printf("touch %d %d\n", pos, info->ip)); + + if ((info->min_touch == -1) + || (pos < info->min_touch)) + info->min_touch = pos; + if (pos > info->max_touch) + info->max_touch = pos; + + info->max_used[pos] = info->ip; +} + +Scheme_Object *scheme_sfs_add_clears(Scheme_Object *expr, Scheme_Object *clears, int pre) +{ + int len, i; + Scheme_Object *loc; + Scheme_Sequence *s; + + if (SCHEME_NULLP(clears)) + return expr; + + len = scheme_list_length(clears); + + s = malloc_sequence(len + 1); + s->so.type = (pre ? scheme_sequence_type : scheme_begin0_sequence_type); + s->count = len + 1; + s->array[pre ? len : 0] = expr; + + for (i = 0; i < len; i++) { + loc = scheme_make_local(scheme_local_type, + SCHEME_INT_VAL(SCHEME_CAR(clears)), + SCHEME_LOCAL_CLEAR_ON_READ); + s->array[i + (pre ? 0 : 1)] = loc; + clears = SCHEME_CDR(clears); + } + + if (pre) + return (Scheme_Object *)s; + else + return scheme_make_syntax_resolved(BEGIN0_EXPD, (Scheme_Object *)s); +} + +static void sfs_note_app(SFS_Info *info, Scheme_Object *rator) +{ + if (!info->pass) { + if (!info->tail_pos) { + if (SCHEME_PRIMP(rator)) { + int opt; + opt = ((Scheme_Prim_Proc_Header *)rator)->flags & SCHEME_PRIM_OPT_MASK; + if (opt >= SCHEME_PRIM_OPT_IMMEDIATE) + /* Don't need to clear stack before an immediate/folding call */ + return; + } + info->max_nontail = info->ip; + } else { + if (!MAX_SFS_CLEARING && (info->selfpos >= 0)) { + if (SAME_TYPE(SCHEME_TYPE(rator), scheme_local_type)) { + if ((SCHEME_LOCAL_POS(rator) + info->stackpos) == info->selfpos) { + /* No point in clearing out any of the closure before the + tail call. */ + int i; + for (i = info->selflen; i--; ) { + if ((info->selfstart + i) != info->tlpos) + scheme_sfs_used(info, (info->selfstart - info->stackpos) + i); + } + } + } + } + } + } +} + +static Scheme_Object *sfs_application(Scheme_Object *o, SFS_Info *info) +{ + Scheme_Object *orig, *naya = NULL; + Scheme_App_Rec *app; + int i, n; + + app = (Scheme_App_Rec *)o; + n = app->num_args + 1; + + scheme_sfs_start_sequence(info, n, 0); + scheme_sfs_push(info, n-1, 0); + + for (i = 0; i < n; i++) { + orig = app->args[i]; + naya = scheme_sfs_expr(orig, info, -1); + app->args[i] = naya; + } + + sfs_note_app(info, app->args[0]); + + scheme_finish_application(app); + + return o; +} + +static Scheme_Object *sfs_application2(Scheme_Object *o, SFS_Info *info) +{ + Scheme_App2_Rec *app; + Scheme_Object *nrator, *nrand; + + app = (Scheme_App2_Rec *)o; + + scheme_sfs_start_sequence(info, 2, 0); + scheme_sfs_push(info, 1, 0); + + nrator = scheme_sfs_expr(app->rator, info, -1); + nrand = scheme_sfs_expr(app->rand, info, -1); + app->rator = nrator; + app->rand = nrand; + + sfs_note_app(info, app->rator); + + set_app2_eval_type(app); + + return o; +} + +static Scheme_Object *sfs_application3(Scheme_Object *o, SFS_Info *info) +{ + Scheme_App3_Rec *app; + Scheme_Object *nrator, *nrand1, *nrand2; + + app = (Scheme_App3_Rec *)o; + + scheme_sfs_start_sequence(info, 3, 0); + scheme_sfs_push(info, 2, 0); + + nrator = scheme_sfs_expr(app->rator, info, -1); + nrand1 = scheme_sfs_expr(app->rand1, info, -1); + nrand2 = scheme_sfs_expr(app->rand2, info, -1); + + app->rator = nrator; + app->rand1 = nrand1; + app->rand2 = nrand2; + + sfs_note_app(info, app->rator); + + set_app3_eval_type(app); + + return o; +} + +static Scheme_Object *sfs_sequence(Scheme_Object *o, SFS_Info *info) +{ + Scheme_Object *orig, *naya; + Scheme_Sequence *seq; + int i, n; + + seq = (Scheme_Sequence *)o; + n = seq->count; + + scheme_sfs_start_sequence(info, n, 1); + + for (i = 0; i < n; i++) { + orig = seq->array[i]; + naya = scheme_sfs_expr(orig, info, -1); + seq->array[i] = naya; + } + + return o; +} + +#define SFS_BRANCH_W 4 + +static Scheme_Object *sfs_one_branch(SFS_Info *info, int ip, + Scheme_Object *vec, int delta, + Scheme_Object *tbranch) +{ + int t_min_t, t_max_t, t_cnt, n, stackpos, i, save_nt, b_end, nt; + Scheme_Object *t_vec, *o; + Scheme_Object *clears = scheme_null; + + info->min_touch = -1; + info->max_touch = -1; + save_nt = info->max_nontail; + + SFS_LOG(printf("%d %d %s %d\n", info->pass, ip, (delta ? "else" : "then"), ip)); + + if (info->pass) { + /* Re-install max_used entries that refer to the branch */ + o = SCHEME_VEC_ELS(vec)[delta * SFS_BRANCH_W]; + t_min_t = SCHEME_INT_VAL(o); + o = SCHEME_VEC_ELS(vec)[(delta * SFS_BRANCH_W) + 2]; + nt = SCHEME_INT_VAL(o); + if (nt > info->max_nontail) + info->max_nontail = nt; + if (t_min_t > -1) { + t_vec = SCHEME_VEC_ELS(vec)[(delta * SFS_BRANCH_W) + 1]; + t_cnt = SCHEME_VEC_SIZE(t_vec); + for (i = 0; i < t_cnt; i++) { + o = SCHEME_VEC_ELS(t_vec)[i]; + if (SCHEME_INTP(o)) { + n = SCHEME_INT_VAL(o); + SFS_LOG(printf(" @%d %d\n", i + t_min_t, n)); + if (info->max_used[i + t_min_t] < n) { + SFS_LOG(printf(" |%d %d\n", i + t_min_t, n)); + info->max_used[i + t_min_t] = n; + info->max_calls[i + t_min_t] = info->max_nontail; + } + } + } + } + /* If the other branch has last use for something not used in this + branch, and if there's a non-tail call in this branch + of later, then we'll have to start with explicit clears. + Note that it doesn't matter whether the other branch actually + clears them (i.e., the relevant non-tail call might be only + in this branch). */ + o = SCHEME_VEC_ELS(vec)[((1 - delta) * SFS_BRANCH_W) + 3]; + b_end = SCHEME_INT_VAL(o); + if (((nt > ip) && (nt < b_end)) /* => non-tail call in branch */ + || (ip < save_nt)) { /* => non-tail call after branches */ + o = SCHEME_VEC_ELS(vec)[(1 - delta) * SFS_BRANCH_W]; + t_min_t = SCHEME_INT_VAL(o); + if (t_min_t > -1) { + int at_ip, pos; + t_vec = SCHEME_VEC_ELS(vec)[((1 - delta) * SFS_BRANCH_W) + 1]; + t_cnt = SCHEME_VEC_SIZE(t_vec); + o = SCHEME_VEC_ELS(vec)[((1 - delta) * SFS_BRANCH_W) + 2]; + nt = SCHEME_INT_VAL(o); + o = SCHEME_VEC_ELS(vec)[((1 - delta) * SFS_BRANCH_W) + 3]; + b_end = SCHEME_INT_VAL(o); + for (i = 0; i < t_cnt; i++) { + o = SCHEME_VEC_ELS(t_vec)[i]; + if (SCHEME_INTP(o)) { + n = SCHEME_INT_VAL(o); + pos = i + t_min_t; + at_ip = info->max_used[pos]; + SFS_LOG(printf(" ?%d %d %d\n", pos, n, at_ip)); + if (((!delta && (at_ip == ip)) + || (delta && (at_ip == n))) + && (at_ip < info->max_calls[pos])) { + /* Add clear */ + SFS_LOG(printf(" !%d %d %d\n", pos, n, at_ip)); + pos -= info->stackpos; + clears = scheme_make_pair(scheme_make_integer(pos), + clears); + } + } + } + } + } + } + + stackpos = info->stackpos; + + tbranch = scheme_sfs_expr(tbranch, info, -1); + + if (info->pass) + info->max_nontail = save_nt; +# if MAX_SFS_CLEARING + else + info->max_nontail = info->ip; +# endif + + tbranch = scheme_sfs_add_clears(tbranch, clears, 1); + + if (!info->pass) { + t_min_t = info->min_touch; + t_max_t = info->max_touch; + if (t_min_t < stackpos) + t_min_t = stackpos; + if (t_max_t < stackpos) + t_max_t = -1; + SFS_LOG(printf("%d %s %d [%d,%d] /%d\n", info->pass, (delta ? "else" : "then"), ip, + t_min_t, t_max_t, stackpos)); + if (t_max_t < 0) { + t_min_t = -1; + t_vec = scheme_false; + } else { + t_cnt = t_max_t - t_min_t + 1; + t_vec = scheme_make_vector(t_cnt, NULL); + for (i = 0; i < t_cnt; i++) { + n = info->max_used[i + t_min_t]; + SFS_LOG(printf("%d %s %d %d -> %d/%d\n", info->pass, (delta ? "else" : "then"), ip, + i + t_min_t, n, info->max_calls[i+ t_min_t])); + if (n > ip) { + SCHEME_VEC_ELS(t_vec)[i] = scheme_make_integer(n); + info->max_used[i + t_min_t] = ip; + } else { + SCHEME_VEC_ELS(t_vec)[i] = scheme_false; + } + } + } + SCHEME_VEC_ELS(vec)[delta * SFS_BRANCH_W] = scheme_make_integer(t_min_t); + SCHEME_VEC_ELS(vec)[(delta * SFS_BRANCH_W) + 1] = t_vec; + SCHEME_VEC_ELS(vec)[(delta * SFS_BRANCH_W) + 2] = scheme_make_integer(info->max_nontail); + SCHEME_VEC_ELS(vec)[(delta * SFS_BRANCH_W) + 3] = scheme_make_integer(info->ip); + } + + info->stackpos = stackpos; + + return tbranch; +} + +static Scheme_Object *sfs_branch(Scheme_Object *o, SFS_Info *info) +{ + Scheme_Branch_Rec *b; + Scheme_Object *t, *tb, *fb, *vec; + int ip, min_t, max_t; + + b = (Scheme_Branch_Rec *)o; + + scheme_sfs_start_sequence(info, 1, 0); + + t = scheme_sfs_expr(b->test, info, -1); + + ip = info->ip; + info->ip++; + /* Use ip to represent all uses in the two branches. + Use ip+1 to represent all non-tail calls in the two branches. */ + + min_t = info->min_touch; + max_t = info->max_touch; + + SFS_LOG(printf(" after test: %d %d\n", min_t, max_t)); + + if (!info->pass) { + vec = scheme_make_vector(SFS_BRANCH_W * 2, NULL); + scheme_sfs_save(info, vec); + } else { + vec = scheme_sfs_next_saved(info); + } + + tb = sfs_one_branch(info, ip, vec, 0, b->tbranch); + + if (!info->pass) { + if ((min_t == -1) + || ((info->min_touch > -1) && (info->min_touch < min_t))) + min_t = info->min_touch; + if (info->max_touch > max_t) + max_t = info->max_touch; + if (info->max_nontail > ip + 1) + info->max_nontail = ip + 1; + } + + fb = sfs_one_branch(info, ip, vec, 1, b->fbranch); + + if (!info->pass) { + if ((min_t == -1) + || ((info->min_touch > -1) && (info->min_touch < min_t))) + min_t = info->min_touch; + if (info->max_touch > max_t) + max_t = info->max_touch; + if (info->max_nontail > ip + 1) + info->max_nontail = ip + 1; + } + + SFS_LOG(printf(" done if: %d %d\n", min_t, max_t)); + + info->min_touch = min_t; + info->max_touch = max_t; + + b->test = t; + b->tbranch = tb; + b->fbranch = fb; + + return o; +} + +static Scheme_Object *sfs_let_value(Scheme_Object *o, SFS_Info *info) +{ + Scheme_Let_Value *lv = (Scheme_Let_Value *)o; + Scheme_Object *body, *rhs, *clears = scheme_null; + int i, pos; + + scheme_sfs_start_sequence(info, 2, 1); + + rhs = scheme_sfs_expr(lv->value, info, -1); + + if (!info->pass + || (info->ip < info->max_nontail)) { + for (i = 0; i < lv->count; i++) { + pos = lv->position + i; + if (!info->pass) + scheme_sfs_used(info, pos); + else { + int spos; + spos = pos + info->stackpos; + if ((info->max_used[spos] == info->ip) + && (info->max_calls[spos] > info->ip)) { + /* No one is using the id after we set it. + We still need to set it, in case it's boxed and shared, + but then remove the binding or box. */ + clears = scheme_make_pair(scheme_make_integer(pos), + clears); + } + } + } + } + + body = scheme_sfs_expr(lv->body, info, -1); + + body = scheme_sfs_add_clears(body, clears, 1); + + lv->value = rhs; + lv->body = body; + + return o; +} + +static Scheme_Object *sfs_let_one(Scheme_Object *o, SFS_Info *info) +{ + Scheme_Let_One *lo = (Scheme_Let_One *)o; + Scheme_Object *body, *rhs, *vec; + int pos, save_mnt; + + scheme_sfs_start_sequence(info, 2, 1); + + scheme_sfs_push(info, 1, 1); + pos = info->stackpos; + save_mnt = info->max_nontail; + + if (!info->pass) { + vec = scheme_make_vector(3, NULL); + scheme_sfs_save(info, vec); + } else { + vec = scheme_sfs_next_saved(info); + if (SCHEME_VEC_SIZE(vec) != 3) + scheme_signal_error("internal error: bad vector length"); + info->max_used[pos] = SCHEME_INT_VAL(SCHEME_VEC_ELS(vec)[0]); + info->max_calls[pos] = SCHEME_INT_VAL(SCHEME_VEC_ELS(vec)[1]); + info->max_nontail = SCHEME_INT_VAL(SCHEME_VEC_ELS(vec)[2]); + } + + rhs = scheme_sfs_expr(lo->value, info, -1); + body = scheme_sfs_expr(lo->body, info, -1); + +# if MAX_SFS_CLEARING + if (!info->pass) + info->max_nontail = info->ip; +# endif + + if (!info->pass) { + int n; + info->max_calls[pos] = info->max_nontail; + n = info->max_used[pos]; + SCHEME_VEC_ELS(vec)[0] = scheme_make_integer(n); + n = info->max_calls[pos]; + SCHEME_VEC_ELS(vec)[1] = scheme_make_integer(n); + SCHEME_VEC_ELS(vec)[2] = scheme_make_integer(info->max_nontail); + } else { + info->max_nontail = save_mnt; + } + + lo->value = rhs; + lo->body = body; + + return o; +} + +static Scheme_Object *sfs_let_void(Scheme_Object *o, SFS_Info *info) +{ + Scheme_Let_Void *lv = (Scheme_Let_Void *)o; + Scheme_Object *body; + int i, pos; + Scheme_Object *vec; + + scheme_sfs_push(info, lv->count, 1); + pos = info->stackpos; + + if (!info->pass) { + vec = scheme_make_vector(lv->count + 1, NULL); + scheme_sfs_save(info, vec); + } else { + vec = scheme_sfs_next_saved(info); + if (!SCHEME_VECTORP(vec)) + scheme_signal_error("internal error: not a vector"); + for (i = 0; i < lv->count; i++) { + info->max_used[pos + i] = SCHEME_INT_VAL(SCHEME_VEC_ELS(vec)[i]); + info->max_calls[pos + i] = SCHEME_INT_VAL(SCHEME_VEC_ELS(vec)[lv->count]); + } + } + + body = scheme_sfs_expr(lv->body, info, -1); + +# if MAX_SFS_CLEARING + if (!info->pass) + info->max_nontail = info->ip; +# endif + + if (!info->pass) { + int n; + SCHEME_VEC_ELS(vec)[lv->count] = scheme_make_integer(info->max_nontail); + for (i = 0; i < lv->count; i++) { + n = info->max_used[pos + i]; + SCHEME_VEC_ELS(vec)[i] = scheme_make_integer(n); + } + } + + lv->body = body; + + return o; +} + +static Scheme_Object *sfs_letrec(Scheme_Object *o, SFS_Info *info) +{ + Scheme_Letrec *lr = (Scheme_Letrec *)o; + Scheme_Object **procs, *v, *clears = scheme_null; + int i, count; + + count = lr->count; + + scheme_sfs_start_sequence(info, count + 1, 1); + + procs = lr->procs; + + for (i = 0; i < count; i++) { + v = scheme_sfs_expr(procs[i], info, i); + + if (SAME_TYPE(SCHEME_TYPE(v), scheme_syntax_type) + && (SCHEME_PINT_VAL(v) == BEGIN0_EXPD)) { + /* Some clearing actions were added to the closure. + Lift them out. */ + int j; + Scheme_Sequence *cseq = (Scheme_Sequence *)SCHEME_IPTR_VAL(v); + for (j = 1; j < cseq->count; j++) { + int pos; + pos = SCHEME_LOCAL_POS(cseq->array[j]); + clears = scheme_make_pair(scheme_make_integer(pos), clears); + } + v = cseq->array[0]; + } + procs[i] = v; + } + + v = scheme_sfs_expr(lr->body, info, -1); + + v = scheme_sfs_add_clears(v, clears, 1); + + lr->body = v; + + return o; +} + +static Scheme_Object *sfs_wcm(Scheme_Object *o, SFS_Info *info) +{ + Scheme_With_Continuation_Mark *wcm = (Scheme_With_Continuation_Mark *)o; + Scheme_Object *k, *v, *b; + + scheme_sfs_start_sequence(info, 3, 1); + + k = scheme_sfs_expr(wcm->key, info, -1); + v = scheme_sfs_expr(wcm->val, info, -1); + b = scheme_sfs_expr(wcm->body, info, -1); + + wcm->key = k; + wcm->val = v; + wcm->body = b; + + return o; +} + +Scheme_Object *scheme_sfs_expr(Scheme_Object *expr, SFS_Info *info, int closure_self_pos) +{ + Scheme_Type type = SCHEME_TYPE(expr); + int seqn, stackpos, tp; + + seqn = info->seqn; + stackpos = info->stackpos; + tp = info->tail_pos; + if (seqn) { + info->seqn = 0; + info->tail_pos = 0; + } + info->ip++; + + switch (type) { + case scheme_local_type: + case scheme_local_unbox_type: + if (!info->pass) + scheme_sfs_used(info, SCHEME_LOCAL_POS(expr)); + else { + int pos, at_ip; + pos = SCHEME_LOCAL_POS(expr); + at_ip = info->max_used[info->stackpos + pos]; + if (at_ip < info->max_calls[info->stackpos + pos]) { + if (at_ip == info->ip) { + /* Clear on read: */ + expr = scheme_make_local(type, pos, SCHEME_LOCAL_CLEAR_ON_READ); + } else { + /* Someone else clears it: */ + expr = scheme_make_local(type, pos, SCHEME_LOCAL_OTHER_CLEARS); + } + } else { +# if MAX_SFS_CLEARING + scheme_signal_error("should have been cleared somewhere"); +# endif + } + } + break; + case scheme_syntax_type: + { + Scheme_Syntax_SFSer f; + Scheme_Object *orig, *naya; + + f = scheme_syntax_sfsers[SCHEME_PINT_VAL(expr)]; + orig = SCHEME_IPTR_VAL(expr); + naya = f(orig, info); + if (!SAME_OBJ(orig, naya)) + expr = naya; + } + break; + case scheme_application_type: + expr = sfs_application(expr, info); + break; + case scheme_application2_type: + expr = sfs_application2(expr, info); + break; + case scheme_application3_type: + expr = sfs_application3(expr, info); + break; + case scheme_sequence_type: + expr = sfs_sequence(expr, info); + break; + case scheme_branch_type: + expr = sfs_branch(expr, info); + break; + case scheme_with_cont_mark_type: + expr = sfs_wcm(expr, info); + break; + case scheme_unclosed_procedure_type: + expr = scheme_sfs_closure(expr, info, closure_self_pos); + break; + case scheme_let_value_type: + expr = sfs_let_value(expr, info); + break; + case scheme_let_void_type: + expr = sfs_let_void(expr, info); + break; + case scheme_letrec_type: + expr = sfs_letrec(expr, info); + break; + case scheme_let_one_type: + expr = sfs_let_one(expr, info); + break; + case scheme_closure_type: + { + Scheme_Closure *c = (Scheme_Closure *)expr; + if (ZERO_SIZED_CLOSUREP(c)) { + Scheme_Object *code; + code = scheme_sfs_closure((Scheme_Object *)c->code, info, closure_self_pos); + if (SAME_TYPE(SCHEME_TYPE(code), scheme_syntax_type) + && (SCHEME_PINT_VAL(code) == BEGIN0_EXPD)) { + Scheme_Sequence *seq = (Scheme_Sequence *)SCHEME_IPTR_VAL(code); + c->code = (Scheme_Closure_Data *)seq->array[0]; + seq->array[0] = expr; + expr = code; + } else { + c->code = (Scheme_Closure_Data *)code; + } + } + } + break; + case scheme_toplevel_type: + { + int c = SCHEME_TOPLEVEL_DEPTH(expr); + if (info->stackpos + c != info->tlpos) + scheme_signal_error("toplevel access not at expected place"); + } + break; + case scheme_case_closure_type: + { + /* FIXME: maybe need to handle eagerly created closure */ + } + break; + default: + break; + } + + info->ip++; + + if (seqn) { + info->seqn = seqn - 1; + memset(info->max_used + info->stackpos, 0, (stackpos - info->stackpos) * sizeof(int)); + memset(info->max_calls + info->stackpos, 0, (stackpos - info->stackpos) * sizeof(int)); + info->stackpos = stackpos; + info->tail_pos = tp; + } + + return expr; +} + /*========================================================================*/ /* JIT */ /*========================================================================*/ @@ -3936,6 +4772,7 @@ static void *compile_k(void) scheme_enable_expression_resolve_lifts(ri); o = scheme_resolve_expr(o, ri); + o = scheme_sfs(o, NULL, ri->max_let_depth); o = scheme_merge_expression_resolve_lifts(o, rp, ri); @@ -6777,12 +7614,12 @@ scheme_do_eval(Scheme_Object *obj, int num_rands, Scheme_Object **rands, case scheme_local_type: { v = RUNSTACK[SCHEME_LOCAL_POS(obj)]; - goto returnv_never_multi; + goto returnv_never_multi; } case scheme_local_unbox_type: { v = SCHEME_ENVBOX_VAL(RUNSTACK[SCHEME_LOCAL_POS(obj)]); - goto returnv_never_multi; + goto returnv_never_multi; } case scheme_syntax_type: { @@ -8491,6 +9328,61 @@ void scheme_pop_prefix(Scheme_Object **rs) #define VALID_VAL 1 #define VALID_BOX 2 #define VALID_TOPLEVELS 3 +#define VALID_VAL_NOCLEAR 4 +#define VALID_BOX_NOCLEAR 5 + +typedef struct Validate_Clearing { + MZTAG_IF_REQUIRED + int stackpos, stacksize; + int *stack; + int ncstackpos, ncstacksize; + int *ncstack; + int self_pos, self_count, self_start; +} Validate_Clearing; + +static struct Validate_Clearing *make_clearing_stack() +{ + Validate_Clearing *vc; + vc = MALLOC_ONE_RT(Validate_Clearing); + SET_REQUIRED_TAG(vc->type = scheme_rt_validate_clearing); + vc->self_pos = -1; + return vc; +} + +static void reset_clearing(struct Validate_Clearing *vc) +{ + vc->stackpos = 0; + vc->ncstackpos = 0; +} + +static void clearing_stack_push(struct Validate_Clearing *vc, int pos, int val) +{ + if (vc->stackpos + 2 > vc->stacksize) { + int *a, sz; + sz = (vc->stacksize ? 2 * vc->stacksize : 32); + a = (int *)scheme_malloc_atomic(sizeof(int) * sz); + memcpy(a, vc->stack, vc->stacksize * sizeof(int)); + vc->stacksize = sz; + vc->stack = a; + } + vc->stack[vc->stackpos] = pos; + vc->stack[vc->stackpos + 1] = val; + vc->stackpos += 2; +} + +static void noclear_stack_push(struct Validate_Clearing *vc, int pos) +{ + if (vc->ncstackpos + 1 > vc->ncstacksize) { + int *a, sz; + sz = (vc->ncstacksize ? 2 * vc->ncstacksize : 32); + a = (int *)scheme_malloc_atomic(sizeof(int) * sz); + memcpy(a, vc->ncstack, vc->ncstacksize * sizeof(int)); + vc->ncstacksize = sz; + vc->ncstack = a; + } + vc->ncstack[vc->ncstackpos] = pos; + vc->ncstackpos += 1; +} void scheme_validate_code(Mz_CPort *port, Scheme_Object *code, int depth, @@ -8499,6 +9391,7 @@ void scheme_validate_code(Mz_CPort *port, Scheme_Object *code, { char *stack; int delta; + struct Validate_Clearing *vc; Validate_TLS tls; depth += ((num_toplevels || num_stxes || num_lifts) ? 1 : 0); @@ -8514,22 +9407,27 @@ void scheme_validate_code(Mz_CPort *port, Scheme_Object *code, tls = MALLOC_N(mzshort*, num_lifts); + vc = make_clearing_stack(); + if (code_vec) { int i, cnt; cnt = SCHEME_VEC_SIZE(code); for (i = 0; i < cnt; i++) { + reset_clearing(vc); scheme_validate_expr(port, SCHEME_VEC_ELS(code)[i], stack, tls, depth, delta, delta, num_toplevels, num_stxes, num_lifts, - NULL, 0); + NULL, 0, 0, + vc, 1); } } else { scheme_validate_expr(port, code, stack, tls, depth, delta, delta, num_toplevels, num_stxes, num_lifts, - NULL, 0); + NULL, 0, 0, + vc, 1); } } @@ -8542,16 +9440,18 @@ static Scheme_Object *validate_k(void) int *args = (int *)(((void **)p->ku.k.p5)[0]); Scheme_Object *app_rator = (Scheme_Object *)(((void **)p->ku.k.p5)[1]); Validate_TLS tls = (Validate_TLS)(((void **)p->ku.k.p5)[2]); + struct Validate_Clearing *vc = (struct Validate_Clearing *)p->ku.k.p4; p->ku.k.p1 = NULL; p->ku.k.p2 = NULL; p->ku.k.p3 = NULL; + p->ku.k.p4 = NULL; p->ku.k.p5 = NULL; scheme_validate_expr(port, expr, stack, tls, args[0], args[1], args[2], args[3], args[4], args[5], - app_rator, args[6]); + app_rator, args[6], args[7], vc, args[8]); return scheme_true; } @@ -8654,11 +9554,13 @@ static int argument_to_arity_error(Scheme_Object *app_rator, int proc_with_refs_ void scheme_validate_closure(Mz_CPort *port, Scheme_Object *expr, char *closure_stack, Validate_TLS tls, - int num_toplevels, int num_stxes, int num_lifts) + int num_toplevels, int num_stxes, int num_lifts, + int self_pos_in_closure) { Scheme_Closure_Data *data = (Scheme_Closure_Data *)expr; int i, sz, cnt, base, base2; char *new_stack; + struct Validate_Clearing *vc; sz = data->max_let_depth; new_stack = scheme_malloc_atomic(sz); @@ -8684,18 +9586,124 @@ void scheme_validate_closure(Mz_CPort *port, Scheme_Object *expr, new_stack[i + base] = closure_stack[i]; } + vc = make_clearing_stack(); + if (self_pos_in_closure >= 0) { + vc->self_pos = base + self_pos_in_closure; + vc->self_count = data->closure_size; + vc->self_start = base; + } + scheme_validate_expr(port, data->code, new_stack, tls, sz, sz, base, num_toplevels, num_stxes, num_lifts, - NULL, 0); + NULL, 0, 0, vc, 1); +} + + +static void validate_unclosed_procedure(Mz_CPort *port, Scheme_Object *expr, + char *stack, Validate_TLS tls, + int depth, int delta, + int num_toplevels, int num_stxes, int num_lifts, + Scheme_Object *app_rator, int proc_with_refs_ok, + int self_pos) +{ + Scheme_Closure_Data *data = (Scheme_Closure_Data *)expr; + int i, cnt, q, p, sz, base, vld, self_pos_in_closure = -1; + mzshort *map; + char *closure_stack; + + if (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_REF_ARGS) { + sz = data->closure_size + data->num_params; + } else { + sz = data->closure_size; + } + map = data->closure_map; + + if (sz) + closure_stack = scheme_malloc_atomic(sz); + else + closure_stack = NULL; + + if (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_REF_ARGS) { + cnt = data->num_params; + base = sz - cnt; + for (i = 0; i < cnt; i++) { + int bit = ((mzshort)1 << (i & (BITS_PER_MZSHORT - 1))); + if (map[data->closure_size + (i / BITS_PER_MZSHORT)] & bit) + vld = VALID_BOX; + else + vld = VALID_VAL; + closure_stack[i + base] = vld; + } + } else { + base = sz; + } + + cnt = data->closure_size; + base = base - cnt; + + for (i = 0; i < cnt; i++) { + q = map[i]; + if (q == self_pos) + self_pos_in_closure = i; + p = q + delta; + if ((q < 0) || (p > depth) || (stack[p] == VALID_NOT)) + scheme_ill_formed_code(port); + vld = stack[p]; + if (vld == VALID_VAL_NOCLEAR) + vld = VALID_VAL; + else if (vld == VALID_BOX_NOCLEAR) + vld = VALID_BOX; + closure_stack[i + base] = vld; + } + + if (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_REF_ARGS) { + if ((proc_with_refs_ok != 1) + && !argument_to_arity_error(app_rator, proc_with_refs_ok)) + scheme_ill_formed_code(port); + } + + if (SCHEME_RPAIRP(data->code)) { + /* Delay validation */ + Scheme_Object *vec; + vec = scheme_make_vector(7, NULL); + SCHEME_VEC_ELS(vec)[0] = SCHEME_CAR(data->code); + SCHEME_VEC_ELS(vec)[1] = (Scheme_Object *)closure_stack; + SCHEME_VEC_ELS(vec)[2] = (Scheme_Object *)tls; + SCHEME_VEC_ELS(vec)[3] = scheme_make_integer(num_toplevels); + SCHEME_VEC_ELS(vec)[4] = scheme_make_integer(num_stxes); + SCHEME_VEC_ELS(vec)[5] = scheme_make_integer(num_lifts); + SCHEME_VEC_ELS(vec)[6] = scheme_make_integer(self_pos_in_closure); + SCHEME_CAR(data->code) = vec; + } else + scheme_validate_closure(port, expr, closure_stack, tls, num_toplevels, num_stxes, num_lifts, self_pos_in_closure); +} + +static void check_self_call_valid(Scheme_Object *rator, Mz_CPort *port, struct Validate_Clearing *vc, + int delta, char *stack) +{ + if ((vc->self_pos >= 0) + && SAME_TYPE(SCHEME_TYPE(rator), scheme_local_type) + && !(SCHEME_LOCAL_FLAGS(rator) & SCHEME_LOCAL_CLEARING_MASK) + && ((SCHEME_LOCAL_POS(rator) + delta) == vc->self_pos)) { + /* For a self call, the JIT needs the closure data to be intact. */ + int i, pos; + for (i = vc->self_count; i--; ) { + pos = i + vc->self_start; + if (stack[pos] == VALID_NOT) + scheme_ill_formed_code(port); + } + } } void scheme_validate_expr(Mz_CPort *port, Scheme_Object *expr, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, int num_toplevels, int num_stxes, int num_lifts, - Scheme_Object *app_rator, int proc_with_refs_ok) + Scheme_Object *app_rator, int proc_with_refs_ok, + int result_ignored, + struct Validate_Clearing *vc, int tailpos) { Scheme_Type type; - int did_one = 0; + int did_one = 0, vc_merge = 0, vc_merge_start = 0; #ifdef DO_STACK_CHECK # include "mzstkchk.h" @@ -8704,11 +9712,12 @@ void scheme_validate_expr(Mz_CPort *port, Scheme_Object *expr, void **pr; int *args; - args = MALLOC_N_ATOMIC(int, 7); + args = MALLOC_N_ATOMIC(int, 8); p->ku.k.p1 = (void *)port; p->ku.k.p2 = (void *)expr; p->ku.k.p3 = (void *)stack; + p->ku.k.p4 = (void *)vc; args[0] = depth; args[1] = letlimit; @@ -8717,6 +9726,7 @@ void scheme_validate_expr(Mz_CPort *port, Scheme_Object *expr, args[4] = num_stxes; args[5] = num_lifts; args[6] = proc_with_refs_ok; + args[7] = result_ignored; pr = MALLOC_N(void*, 3); pr[0] = (void *)args; @@ -8797,16 +9807,37 @@ void scheme_validate_expr(Mz_CPort *port, Scheme_Object *expr, if ((q < 0) || (p >= depth)) scheme_ill_formed_code(port); - if (stack[p] != VALID_VAL) { - if ((proc_with_refs_ok >= 2) && (stack[p] == VALID_BOX) - && scheme_validate_rator_wants_box(app_rator, proc_with_refs_ok - 2, 1, - tls, num_toplevels, num_stxes, num_lifts)) { + if ((stack[p] != VALID_VAL) && (stack[p] != VALID_VAL_NOCLEAR)) { + if (result_ignored && ((stack[p] == VALID_BOX) || (stack[p] == VALID_BOX_NOCLEAR))) { + /* ok to look up and ignore box */ + } else if ((proc_with_refs_ok >= 2) + && ((stack[p] == VALID_BOX) || (stack[p] == VALID_BOX_NOCLEAR)) + && scheme_validate_rator_wants_box(app_rator, proc_with_refs_ok - 2, 1, + tls, num_toplevels, num_stxes, num_lifts)) { /* It's ok - the function wants us to pass it a box, and we did. */ app_rator = NULL; } else scheme_ill_formed_code(port); } + + if (SCHEME_LOCAL_FLAGS(expr) & SCHEME_LOCAL_CLEAR_ON_READ) { + if ((stack[p] == VALID_VAL_NOCLEAR) || (stack[p] == VALID_BOX_NOCLEAR)) + scheme_ill_formed_code(port); + if (p >= letlimit) + clearing_stack_push(vc, p, stack[p]); + stack[p] = VALID_NOT; + } else if (!(SCHEME_LOCAL_FLAGS(expr) & SCHEME_LOCAL_OTHER_CLEARS)) { + if (stack[p] == VALID_BOX) { + if (p >= letlimit) + noclear_stack_push(vc, p); + stack[p] = VALID_BOX_NOCLEAR; + } else if (stack[p] == VALID_VAL) { + if (p >= letlimit) + noclear_stack_push(vc, p); + stack[p] = VALID_VAL_NOCLEAR; + } + } } break; case scheme_local_unbox_type: @@ -8814,8 +9845,23 @@ void scheme_validate_expr(Mz_CPort *port, Scheme_Object *expr, int q = SCHEME_LOCAL_POS(expr); int p = q + delta; - if ((q < 0) || (p >= depth) || (stack[p] != VALID_BOX)) + if ((q < 0) || (p >= depth) || ((stack[p] != VALID_BOX) + && (stack[p] != VALID_BOX_NOCLEAR))) scheme_ill_formed_code(port); + + if (SCHEME_LOCAL_FLAGS(expr) & SCHEME_LOCAL_CLEAR_ON_READ) { + if (stack[p] == VALID_BOX_NOCLEAR) + scheme_ill_formed_code(port); + if (p >= letlimit) + clearing_stack_push(vc, p, stack[p]); + stack[p] = VALID_NOT; + } else if (!(SCHEME_LOCAL_FLAGS(expr) & SCHEME_LOCAL_OTHER_CLEARS)) { + if (stack[p] == VALID_BOX) { + if (p >= letlimit) + noclear_stack_push(vc, p); + stack[p] = VALID_BOX_NOCLEAR; + } + } } break; case scheme_syntax_type: @@ -8827,7 +9873,8 @@ void scheme_validate_expr(Mz_CPort *port, Scheme_Object *expr, scheme_ill_formed_code(port); f = scheme_syntax_validaters[p]; - f((Scheme_Object *)SCHEME_IPTR_VAL(expr), port, stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts); + f((Scheme_Object *)SCHEME_IPTR_VAL(expr), port, stack, tls, depth, letlimit, delta, + num_toplevels, num_stxes, num_lifts, vc, tailpos); } break; case scheme_application_type: @@ -8844,8 +9891,11 @@ void scheme_validate_expr(Mz_CPort *port, Scheme_Object *expr, for (i = 0; i < n; i++) { scheme_validate_expr(port, app->args[i], stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - i ? app->args[0] : NULL, i + 1); + i ? app->args[0] : NULL, i + 1, 0, vc, 0); } + + if (tailpos) + check_self_call_valid(app->args[0], port, vc, delta, stack); } break; case scheme_application2_type: @@ -8858,9 +9908,12 @@ void scheme_validate_expr(Mz_CPort *port, Scheme_Object *expr, stack[delta] = VALID_NOT; scheme_validate_expr(port, app->rator, stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - NULL, 1); + NULL, 1, 0, vc, 0); scheme_validate_expr(port, app->rand, stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - app->rator, 2); + app->rator, 2, 0, vc, 0); + + if (tailpos) + check_self_call_valid(app->rator, port, vc, delta, stack); } break; case scheme_application3_type: @@ -8874,11 +9927,14 @@ void scheme_validate_expr(Mz_CPort *port, Scheme_Object *expr, stack[delta+1] = VALID_NOT; scheme_validate_expr(port, app->rator, stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - NULL, 1); + NULL, 1, 0, vc, 0); scheme_validate_expr(port, app->rand1, stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - app->rator, 2); + app->rator, 2, 0, vc, 0); scheme_validate_expr(port, app->rand2, stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - app->rator, 3); + app->rator, 3, 0, vc, 0); + + if (tailpos) + check_self_call_valid(app->rator, port, vc, delta, stack); } break; case scheme_sequence_type: @@ -8891,7 +9947,7 @@ void scheme_validate_expr(Mz_CPort *port, Scheme_Object *expr, for (i = 0; i < cnt - 1; i++) { scheme_validate_expr(port, seq->array[i], stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - NULL, 0); + NULL, 0, 1, vc, 0); } expr = seq->array[cnt - 1]; @@ -8901,15 +9957,44 @@ void scheme_validate_expr(Mz_CPort *port, Scheme_Object *expr, case scheme_branch_type: { Scheme_Branch_Rec *b; + int vc_pos, vc_ncpos; + b = (Scheme_Branch_Rec *)expr; scheme_validate_expr(port, b->test, stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - NULL, 0); + NULL, 0, 0, vc, 0); /* This is where letlimit is useful. It prevents let-assignment in the "then" branch that could permit bad code in the "else" branch (or the same thing with either branch affecting later code in a sequence). */ letlimit = delta; + vc_pos = vc->stackpos; + vc_ncpos = vc->ncstackpos; scheme_validate_expr(port, b->tbranch, stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - NULL, 0); + NULL, 0, result_ignored, vc, tailpos); + + /* Rewind clears and noclears, but also save the clears, + so that the branches' effects can be merged. */ + { + int i, j; + + if (!vc_merge) { + vc_merge = 1; + vc_merge_start = vc_pos; + } + + for (i = vc->stackpos - 2; i >= vc_pos; i -= 2) { + stack[vc->stack[i]] = vc->stack[i + 1]; + } + + for (i = vc->ncstackpos - 1; i >= vc_ncpos; i--) { + j = vc->ncstack[i]; + if (stack[j] == VALID_VAL_NOCLEAR) + stack[j] = VALID_VAL; + else if (stack[j] == VALID_BOX_NOCLEAR) + stack[j] = VALID_BOX; + } + vc->ncstackpos = vc_ncpos; + } + expr = b->fbranch; goto top; } @@ -8919,9 +10004,9 @@ void scheme_validate_expr(Mz_CPort *port, Scheme_Object *expr, Scheme_With_Continuation_Mark *wcm = (Scheme_With_Continuation_Mark *)expr; scheme_validate_expr(port, wcm->key, stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - NULL, 0); + NULL, 0, 0, vc, 0); scheme_validate_expr(port, wcm->val, stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - NULL, 0); + NULL, 0, 0, vc, 0); expr = wcm->body; goto top; } @@ -8943,68 +10028,9 @@ void scheme_validate_expr(Mz_CPort *port, Scheme_Object *expr, break; case scheme_unclosed_procedure_type: { - Scheme_Closure_Data *data = (Scheme_Closure_Data *)expr; - int i, cnt, q, p, sz, base, vld; - mzshort *map; - char *closure_stack; - - if (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_REF_ARGS) { - sz = data->closure_size + data->num_params; - } else { - sz = data->closure_size; - } - map = data->closure_map; - - if (sz) - closure_stack = scheme_malloc_atomic(sz); - else - closure_stack = NULL; - - if (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_REF_ARGS) { - cnt = data->num_params; - base = sz - cnt; - for (i = 0; i < cnt; i++) { - int bit = ((mzshort)1 << (i & (BITS_PER_MZSHORT - 1))); - if (map[data->closure_size + (i / BITS_PER_MZSHORT)] & bit) - vld = VALID_BOX; - else - vld = VALID_VAL; - closure_stack[i + base] = vld; - } - } else { - base = sz; - } - - cnt = data->closure_size; - base = base - cnt; - - for (i = 0; i < cnt; i++) { - q = map[i]; - p = q + delta; - if ((q < 0) || (p > depth) || (stack[p] == VALID_NOT)) - scheme_ill_formed_code(port); - closure_stack[i + base] = stack[p]; - } - - if (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_REF_ARGS) { - if ((proc_with_refs_ok != 1) - && !argument_to_arity_error(app_rator, proc_with_refs_ok)) - scheme_ill_formed_code(port); - } - - if (SCHEME_RPAIRP(data->code)) { - /* Delay validation */ - Scheme_Object *vec; - vec = scheme_make_vector(6, NULL); - SCHEME_VEC_ELS(vec)[0] = SCHEME_CAR(data->code); - SCHEME_VEC_ELS(vec)[1] = (Scheme_Object *)closure_stack; - SCHEME_VEC_ELS(vec)[2] = (Scheme_Object *)tls; - SCHEME_VEC_ELS(vec)[3] = scheme_make_integer(num_toplevels); - SCHEME_VEC_ELS(vec)[4] = scheme_make_integer(num_stxes); - SCHEME_VEC_ELS(vec)[5] = scheme_make_integer(num_lifts); - SCHEME_CAR(data->code) = vec; - } else - scheme_validate_closure(port, expr, closure_stack, tls, num_toplevels, num_stxes, num_lifts); + validate_unclosed_procedure(port, expr, stack, tls, + depth, delta, num_toplevels, num_stxes, num_lifts, + app_rator, proc_with_refs_ok, -1); } break; case scheme_let_value_type: @@ -9013,7 +10039,7 @@ void scheme_validate_expr(Mz_CPort *port, Scheme_Object *expr, int q, p, c, i; scheme_validate_expr(port, lv->value, stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - NULL, 0); + NULL, 0, 0, vc, 0); memset(stack, VALID_NOT, delta); c = lv->count; @@ -9023,13 +10049,17 @@ void scheme_validate_expr(Mz_CPort *port, Scheme_Object *expr, for (i = 0; i < c; i++, p++) { if ((q < 0) || (SCHEME_LET_AUTOBOX(lv) && ((p >= depth) - || (stack[p] != VALID_BOX))) + || ((stack[p] != VALID_BOX) + && (stack[p] != VALID_BOX_NOCLEAR)))) || (!SCHEME_LET_AUTOBOX(lv) && ((p >= letlimit) - || ((stack[p] != VALID_VAL) && (stack[p] != VALID_NOT))))) + || ((stack[p] != VALID_VAL) + && (stack[p] != VALID_VAL_NOCLEAR) + && (stack[p] != VALID_NOT))))) scheme_ill_formed_code(port); if (!SCHEME_LET_AUTOBOX(lv)) { - stack[p] = VALID_VAL; + if (stack[p] != VALID_VAL_NOCLEAR) + stack[p] = VALID_VAL; } } @@ -9081,8 +10111,9 @@ void scheme_validate_expr(Mz_CPort *port, Scheme_Object *expr, } for (i = 0; i < c; i++) { - scheme_validate_expr(port, l->procs[i], stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - NULL, 0); + validate_unclosed_procedure(port, l->procs[i], stack, tls, + depth, delta, num_toplevels, num_stxes, num_lifts, + NULL, 0, i); } expr = l->body; @@ -9099,7 +10130,7 @@ void scheme_validate_expr(Mz_CPort *port, Scheme_Object *expr, stack[delta] = VALID_NOT; scheme_validate_expr(port, lo->value, stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - NULL, 0); + NULL, 0, 0, vc, 0); stack[delta] = VALID_VAL; expr = lo->body; @@ -9129,6 +10160,15 @@ void scheme_validate_expr(Mz_CPort *port, Scheme_Object *expr, if (scheme_validate_rator_wants_box(app_rator, proc_with_refs_ok - 2, 0, tls, num_toplevels, num_stxes, num_lifts)) scheme_ill_formed_code(port); + + if (vc_merge) { + /* Re-clear to merge effects from branches */ + int i, p; + for (i = vc_merge_start; i < vc->stackpos; i += 2) { + p = vc->stack[i]; + stack[p] = VALID_NOT; + } + } } void scheme_validate_toplevel(Scheme_Object *expr, Mz_CPort *port, @@ -9143,7 +10183,8 @@ void scheme_validate_toplevel(Scheme_Object *expr, Mz_CPort *port, scheme_validate_expr(port, expr, stack, tls, depth, delta, delta, num_toplevels, num_stxes, num_lifts, - NULL, skip_refs_check ? 1 : 0); + NULL, skip_refs_check ? 1 : 0, 0, + make_clearing_stack(), 0); } void scheme_validate_boxenv(int p, Mz_CPort *port, char *stack, int depth, int delta) @@ -9245,6 +10286,19 @@ static Scheme_Object *write_syntax(Scheme_Object *obj) idx = scheme_make_integer(c); protect_after = scheme_syntax_protect_afters[c]; + if (c == BEGIN0_EXPD) { + Scheme_Object *v; + v = SCHEME_PTR_VAL(obj); + switch (SCHEME_TYPE(v)) { + case scheme_sequence_type: + case scheme_begin0_sequence_type: + break; + default: + *(long *)0x0 = 1; + break; + } + } + l = rest = (Scheme_Object *)SCHEME_IPTR_VAL(obj); if (protect_after == -2) { /* -2 => protect first element of vector */ @@ -9389,6 +10443,7 @@ static void register_traversers(void) { GC_REG_TRAV(scheme_rt_compile_info, mark_comp_info); GC_REG_TRAV(scheme_rt_saved_stack, mark_saved_stack); + GC_REG_TRAV(scheme_rt_validate_clearing, mark_validate_clearing); } END_XFORM_SKIP; diff --git a/src/mzscheme/src/fun.c b/src/mzscheme/src/fun.c index ada5325a3b..7adda10005 100644 --- a/src/mzscheme/src/fun.c +++ b/src/mzscheme/src/fun.c @@ -647,8 +647,7 @@ scheme_make_folding_prim(Scheme_Prim *fun, const char *name, { return make_prim_closure(fun, 1, name, mina, maxa, (folding - ? (SCHEME_PRIM_IS_FOLDING - | SCHEME_PRIM_IS_NONCM) + ? SCHEME_PRIM_OPT_FOLDING : 0), 1, 1, 0, 0, NULL); @@ -660,9 +659,22 @@ scheme_make_noncm_prim(Scheme_Prim *fun, const char *name, { /* A non-cm primitive leaves the mark stack unchanged when it returns, it can't return multiple values or a tail call, and it cannot - use its third argument (i.e., the closure pointer) */ + use its third argument (i.e., the closure pointer). */ return make_prim_closure(fun, 1, name, mina, maxa, - SCHEME_PRIM_IS_NONCM, + SCHEME_PRIM_OPT_NONCM, + 1, 1, + 0, 0, NULL); +} + +Scheme_Object * +scheme_make_immed_prim(Scheme_Prim *fun, const char *name, + mzshort mina, mzshort maxa) +{ + /* An immediate primitive is a non-cm primitive, and it doesn't + extend the continuation in a way that interacts with space safety, except + maybe to raise an exception. */ + return make_prim_closure(fun, 1, name, mina, maxa, + SCHEME_PRIM_OPT_IMMEDIATE, 1, 1, 0, 0, NULL); } @@ -693,7 +705,7 @@ Scheme_Object *scheme_make_folding_prim_closure(Scheme_Primitive_Closure_Proc *p { return make_prim_closure((Scheme_Prim *)prim, 1, name, mina, maxa, (functional - ? SCHEME_PRIM_IS_FOLDING + ? SCHEME_PRIM_OPT_FOLDING : 0), 1, 1, 1, size, vals); @@ -721,7 +733,7 @@ scheme_make_closed_prim_w_everything(Scheme_Closed_Prim *fun, prim->name = name; prim->mina = mina; prim->maxa = maxa; - prim->pp.flags = ((folding ? SCHEME_PRIM_IS_FOLDING : 0) + prim->pp.flags = ((folding ? SCHEME_PRIM_OPT_FOLDING : 0) | (scheme_defining_primitives ? SCHEME_PRIM_IS_PRIMITIVE : 0) | (hasr ? SCHEME_PRIM_IS_MULTI_RESULT : 0)); @@ -908,7 +920,8 @@ void scheme_delay_load_closure(Scheme_Closure_Data *data) (Validate_TLS)SCHEME_VEC_ELS(vinfo)[2], SCHEME_INT_VAL(SCHEME_VEC_ELS(vinfo)[3]), SCHEME_INT_VAL(SCHEME_VEC_ELS(vinfo)[4]), - SCHEME_INT_VAL(SCHEME_VEC_ELS(vinfo)[5])); + SCHEME_INT_VAL(SCHEME_VEC_ELS(vinfo)[5]), + SCHEME_INT_VAL(SCHEME_VEC_ELS(vinfo)[6])); } } } @@ -1024,6 +1037,98 @@ Scheme_Object *scheme_shift_closure_compilation(Scheme_Object *_data, int delta, return _data; } +Scheme_Object *scheme_sfs_closure(Scheme_Object *expr, SFS_Info *info, int self_pos) +{ + Scheme_Closure_Data *data = (Scheme_Closure_Data *)expr; + Scheme_Object *code; + int i, size, has_tl = 0; + + size = data->closure_size; + if (size) { + if (info->stackpos + data->closure_map[size - 1] == info->tlpos) { + has_tl = 1; + --size; + } + } + + if (!info->pass) { + for (i = size; i--; ) { + scheme_sfs_used(info, data->closure_map[i]); + } + } else { + /* Check whether we need to zero out any stack positions + after capturing them in a closure: */ + Scheme_Object *clears = scheme_null; + + if (info->ip < info->max_nontail) { + int pos, ip; + for (i = size; i--; ) { + pos = data->closure_map[i] + info->stackpos; + if (pos < info->depth) { + ip = info->max_used[pos]; + if ((ip == info->ip) + && (ip < info->max_calls[pos])) { + pos -= info->stackpos; + clears = scheme_make_pair(scheme_make_integer(pos), + clears); + } + } + } + } + + return scheme_sfs_add_clears(expr, clears, 0); + } + + if (!(SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_SFS)) { + SCHEME_CLOSURE_DATA_FLAGS(data) |= CLOS_SFS; + info = scheme_new_sfs_info(data->max_let_depth); + scheme_sfs_push(info, data->closure_size + data->num_params, 1); + + if (has_tl) + info->tlpos = info->stackpos + data->closure_size - 1; + + if (self_pos >= 0) { + for (i = size; i--; ) { + if (data->closure_map[i] == self_pos) { + info->selfpos = info->stackpos + i; + info->selfstart = info->stackpos; + info->selflen = data->closure_size; + break; + } + } + } + + code = scheme_sfs(data->code, info, data->max_let_depth); + + /* If any arguments go unused, and if there's a non-tail, + non-immediate call in the body, then we flush the + unused arguments at the start of the body. We assume that + the closure values are used (otherwise they wouldn't + be in the closure). */ + if (info->max_nontail) { + int i, pos, cnt; + Scheme_Object *clears = scheme_null; + + cnt = data->num_params; + for (i = 0; i < cnt; i++) { + pos = data->max_let_depth - (cnt - i); + if (!info->max_used[pos]) { + pos = i + data->closure_size; + clears = scheme_make_pair(scheme_make_integer(pos), + clears); + } + } + + if (SCHEME_PAIRP(clears)) + code = scheme_sfs_add_clears(code, clears, 1); + } + + data->code = code; + } + + return expr; +} + int scheme_closure_body_size(Scheme_Closure_Data *data, int check_assign) { int i; diff --git a/src/mzscheme/src/jit.c b/src/mzscheme/src/jit.c index 545363315c..5f0070afdf 100644 --- a/src/mzscheme/src/jit.c +++ b/src/mzscheme/src/jit.c @@ -857,6 +857,19 @@ static int mz_is_closure(mz_jit_state *jitter, int i, int arity, int *_flags) return 0; } +static int stack_safety(mz_jit_state *jitter, int cnt, int offset) +{ + /* To preserve space safety, we must initialize any stack room + that we make, so that whatever happens to be there isn't + traversed in case of a GC. */ + int i; + for (i = 0; i < cnt; i++) { + jit_stxi_p(WORDS_TO_BYTES(i+offset), JIT_RUNSTACK, JIT_RUNSTACK); + CHECK_LIMIT(); + } + return 1; +} + #define mz_pushr_p(x) mz_pushr_p_it(jitter, x) #define mz_popr_p(x) mz_popr_p_it(jitter, x) @@ -1275,8 +1288,12 @@ static int inlined_nary_prim(Scheme_Object *o, Scheme_Object *_app) static int is_noncm(Scheme_Object *a, mz_jit_state *jitter, int depth, int stack_start) { if (SCHEME_PRIMP(a)) { - if (((Scheme_Prim_Proc_Header *)a)->flags & SCHEME_PRIM_IS_NONCM) - return 1; + int opts; + opts = ((Scheme_Prim_Proc_Header *)a)->flags & SCHEME_PRIM_OPT_MASK; + if (opts >= SCHEME_PRIM_OPT_NONCM) + /* Structure-type predicates are handled specially, so don't claim NONCM: */ + if (!(((Scheme_Prim_Proc_Header *)a)->flags & SCHEME_PRIM_IS_STRUCT_PRED)) + return 1; } if (depth @@ -1409,6 +1426,82 @@ static int is_simple(Scheme_Object *obj, int depth, int just_markless, mz_jit_st return (type > _scheme_values_types_); } +static int is_non_gc(Scheme_Object *obj, int depth) +{ + /* Return 1 if evaluating `obj' can't trigger a GC. */ + Scheme_Type type; + + type = SCHEME_TYPE(obj); + + switch (type) { + case scheme_syntax_type: + break; + + case scheme_branch_type: + if (depth) { + Scheme_Branch_Rec *b = (Scheme_Branch_Rec *)obj; + return (is_non_gc(b->test, depth - 1) + && is_non_gc(b->tbranch, depth - 1) + && is_non_gc(b->fbranch, depth - 1)); + } + break; + + case scheme_let_value_type: + if (depth) { + Scheme_Let_Value *lv = (Scheme_Let_Value *)obj; + if (SCHEME_LET_AUTOBOX(lv)) + return 0; + return is_non_gc(lv->body, depth - 1); + } + break; + case scheme_let_one_type: + if (depth) { + return (is_non_gc(((Scheme_Let_One *)obj)->value, depth - 1) + && is_non_gc(((Scheme_Let_One *)obj)->body, depth - 1)); + } + break; + case scheme_let_void_type: + if (depth) { + Scheme_Let_Void *lv = (Scheme_Let_Void *)obj; + if (SCHEME_LET_AUTOBOX(lv)) + return 0; + return is_non_gc(lv->body, depth - 1); + } + break; + case scheme_letrec_type: + break; + + case scheme_application_type: + break; + case scheme_application2_type: + break; + case scheme_application3_type: + break; + + case scheme_toplevel_type: + break; + case scheme_unclosed_procedure_type: + break; + + case scheme_quote_syntax_type: + case scheme_local_type: + case scheme_local_unbox_type: + return 1; + break; + } + + return (type > _scheme_values_types_); +} + +static int ok_to_move_local(Scheme_Object *obj) +{ + if (SAME_TYPE(SCHEME_TYPE(obj), scheme_local_type) + && !(SCHEME_LOCAL_FLAGS(obj) & SCHEME_LOCAL_CLEARING_MASK)) { + return 1; + } else + return 0; +} + static int is_constant_and_avoids_r1(Scheme_Object *obj) { Scheme_Type t = SCHEME_TYPE(obj); @@ -1417,7 +1510,7 @@ static int is_constant_and_avoids_r1(Scheme_Object *obj) return ((SCHEME_TOPLEVEL_FLAGS(obj) & SCHEME_TOPLEVEL_CONST) ? 1 : 0); - } else if (SAME_TYPE(t, scheme_local_type)) { + } else if (SAME_TYPE(t, scheme_local_type) && ok_to_move_local(obj)) { return 1; } else return (t >= _scheme_compiled_values_types_); @@ -2085,10 +2178,10 @@ static int is_a_procedure(Scheme_Object *v, mz_jit_state *jitter) static int generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_rands, mz_jit_state *jitter, int is_tail, int multi_ok) { - int i, offset; + int i, offset, need_safety = 0; int direct_prim = 0, need_non_tail = 0, direct_native = 0, direct_self = 0; int proc_already_in_place = 0; - Scheme_Object *rator, *v; + Scheme_Object *rator, *v, *arg; int reorder_ok = 0; int args_already_in_place = 0; START_JIT_DATA(); @@ -2106,7 +2199,7 @@ static int generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ } else { Scheme_Type t; t = SCHEME_TYPE(rator); - if (t == scheme_local_type) { + if ((t == scheme_local_type) && ok_to_move_local(rator)) { /* We can re-order evaluation of the rator. */ reorder_ok = 1; @@ -2181,7 +2274,8 @@ static int generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ mz_runstack_skipped(jitter, num_rands); for (i = 0; i < num_rands; i++) { v = (alt_rands ? alt_rands[i+1] : app->args[i+1]); - if (SAME_TYPE(SCHEME_TYPE(v), scheme_local_type)) { + if (SAME_TYPE(SCHEME_TYPE(v), scheme_local_type) + && !(SCHEME_LOCAL_FLAGS(v) & SCHEME_LOCAL_OTHER_CLEARS)) { int pos; pos = mz_remap(SCHEME_LOCAL_POS(v)); if (pos == (jitter->depth + args_already_in_place)) @@ -2202,6 +2296,7 @@ static int generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ if (num_rands) { if (!direct_prim || (num_rands > 1)) { jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(num_rands)); + need_safety = num_rands; CHECK_RUNSTACK_OVERFLOW(); mz_runstack_pushed(jitter, num_rands); } else { @@ -2224,6 +2319,12 @@ static int generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ offset = 0; if (!direct_prim && !reorder_ok && !direct_self) { + if (need_safety && !is_non_gc(rator, INIT_SIMPLE_DEPTH)) { + stack_safety(jitter, need_safety, offset); + CHECK_LIMIT(); + need_safety = 0; + } + generate_non_tail(rator, jitter, 0, !need_non_tail); CHECK_LIMIT(); @@ -2239,8 +2340,11 @@ static int generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ can move the proc directly to V1. */ jit_movr_p(JIT_V1, JIT_R0); proc_already_in_place = 1; - } else + } else { jit_stxi_p(WORDS_TO_BYTES(num_rands - 1 + offset), JIT_RUNSTACK, JIT_R0); + if (need_safety) + need_safety--; + } } else { jit_movr_p(JIT_V1, JIT_R0); } @@ -2248,10 +2352,15 @@ static int generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ for (i = 0; i < num_rands; i++) { PAUSE_JIT_DATA(); - generate_non_tail((alt_rands - ? alt_rands[i+1+args_already_in_place] - : app->args[i+1+args_already_in_place]), - jitter, 0, !need_non_tail); + arg = (alt_rands + ? alt_rands[i+1+args_already_in_place] + : app->args[i+1+args_already_in_place]); + if (need_safety && !is_non_gc(arg, INIT_SIMPLE_DEPTH)) { + stack_safety(jitter, need_safety - i, offset + i); + CHECK_LIMIT(); + need_safety = 0; + } + generate_non_tail(arg, jitter, 0, !need_non_tail); RESUME_JIT_DATA(); CHECK_LIMIT(); if ((i == num_rands - 1) && !direct_prim && !reorder_ok && !direct_self && !proc_already_in_place) { @@ -2694,9 +2803,9 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj rand = rand2; rand2 = NULL; reversed = 1; - } else if ((SAME_TYPE(SCHEME_TYPE(rand2), scheme_local_type) + } else if ((ok_to_move_local(rand2) || SCHEME_INTP(rand2)) - && !(SAME_TYPE(SCHEME_TYPE(rand), scheme_local_type) + && !(ok_to_move_local(rand) || SCHEME_INTP(rand))) { /* Second expression is side-effect-free, unlike the first; swap order and use the fast path for when the first arg is @@ -2715,7 +2824,7 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj } if (rand2) { - simple_rand = (SAME_TYPE(SCHEME_TYPE(rand), scheme_local_type) + simple_rand = (ok_to_move_local(rand) || SCHEME_INTP(rand)); } else simple_rand = 0; @@ -2728,11 +2837,13 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj mz_runstack_skipped(jitter, skipped); if (rand2 && !simple_rand) { + mz_runstack_skipped(jitter, 1); + generate_non_tail(rand, jitter, 0, 1); + mz_runstack_unskipped(jitter, 1); + CHECK_LIMIT(); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); CHECK_RUNSTACK_OVERFLOW(); mz_runstack_pushed(jitter, 1); - generate_non_tail(rand, jitter, 0, 1); - CHECK_LIMIT(); jit_str_p(JIT_RUNSTACK, JIT_R0); } @@ -3618,14 +3729,16 @@ static int generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_ mz_runstack_unskipped(jitter, 2); } else { + mz_runstack_skipped(jitter, 2); + generate_non_tail(rand1, jitter, 0, 1); + mz_runstack_unskipped(jitter, 2); + CHECK_LIMIT(); + jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); CHECK_RUNSTACK_OVERFLOW(); mz_runstack_pushed(jitter, 1); - mz_runstack_skipped(jitter, 1); - - generate_non_tail(rand1, jitter, 0, 1); - CHECK_LIMIT(); jit_str_p(JIT_RUNSTACK, JIT_R0); + mz_runstack_skipped(jitter, 1); generate_non_tail(rand2, jitter, 0, 1); CHECK_LIMIT(); @@ -3810,7 +3923,7 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i __END_SHORT_JUMPS__(branch_short); } else { /* Two complex expressions: */ - generate_two_args(a1, a2, jitter, 0); + generate_two_args(a2, a1, jitter, 0); __START_SHORT_JUMPS__(branch_short); @@ -3902,15 +4015,18 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i mz_runstack_skipped(jitter, 1); if (!simple) { - jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); - CHECK_RUNSTACK_OVERFLOW(); - mz_runstack_pushed(jitter, 1); + mz_runstack_skipped(jitter, 1); } generate_non_tail(app->rand1, jitter, 0, 1); CHECK_LIMIT(); if (!simple) { + mz_runstack_unskipped(jitter, 1); + jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); + CHECK_RUNSTACK_OVERFLOW(); + mz_runstack_pushed(jitter, 1); + jit_str_p(JIT_RUNSTACK, JIT_R0); generate_non_tail(app->rand2, jitter, 0, 1); @@ -4104,6 +4220,8 @@ static int generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(pushed)); CHECK_RUNSTACK_OVERFLOW(); mz_runstack_pushed(jitter, pushed); + stack_safety(jitter, pushed, 0); + CHECK_LIMIT(); } generate_non_tail(app->args[1], jitter, 0, 1); @@ -4568,12 +4686,15 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m /* Other parts of the JIT rely on this code modifying R0, only */ int pos; START_JIT_DATA(); - LOG_IT(("local\n")); pos = mz_remap(SCHEME_LOCAL_POS(obj)); + LOG_IT(("local %d [%d]\n", pos, SCHEME_LOCAL_FLAGS(obj))); if (pos || (mz_CURRENT_STATUS() != mz_RS_R0_HAS_RUNSTACK0)) { jit_ldxi_p(JIT_R0, JIT_RUNSTACK, WORDS_TO_BYTES(pos)); VALIDATE_RESULT(JIT_R0); } + if (SCHEME_LOCAL_FLAGS(obj) & SCHEME_LOCAL_CLEAR_ON_READ) { + jit_stxi_p(WORDS_TO_BYTES(pos), JIT_RUNSTACK, JIT_RUNSTACK); + } END_JIT_DATA(2); return 1; } @@ -4586,6 +4707,10 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m pos = mz_remap(SCHEME_LOCAL_POS(obj)); jit_ldxi_p(JIT_R0, JIT_RUNSTACK, WORDS_TO_BYTES(pos)); jit_ldr_p(JIT_R0, JIT_R0); + if (SCHEME_LOCAL_FLAGS(obj) & SCHEME_LOCAL_CLEAR_ON_READ) { + LOG_IT(("clear-on-read\n")); + jit_stxi_p(WORDS_TO_BYTES(pos), JIT_RUNSTACK, JIT_RUNSTACK); + } VALIDATE_RESULT(JIT_R0); END_JIT_DATA(3); @@ -5036,6 +5161,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m nsrs = jitter->need_set_rs; PAUSE_JIT_DATA(); LOG_IT(("...then...\n")); + FOR_LOG(++jitter->log_depth); g1 = generate(branch->tbranch, jitter, is_tail, multi_ok); RESUME_JIT_DATA(); CHECK_LIMIT(); @@ -5077,7 +5203,9 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m } __END_SHORT_JUMPS__(then_short_ok); PAUSE_JIT_DATA(); + FOR_LOG(jitter->log_depth--); LOG_IT(("...else\n")); + FOR_LOG(++jitter->log_depth); g2 = generate(branch->fbranch, jitter, is_tail, multi_ok); RESUME_JIT_DATA(); CHECK_LIMIT(); @@ -5094,6 +5222,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m mz_patch_ucbranch(ref2); __END_SHORT_JUMPS__(else_short_ok); } + FOR_LOG(jitter->log_depth--); END_JIT_DATA(12); @@ -5218,6 +5347,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(c)); CHECK_RUNSTACK_OVERFLOW(); + stack_safety(jitter, c, 0); mz_runstack_pushed(jitter, c); if (SCHEME_LET_AUTOBOX(lv)) { @@ -5301,14 +5431,19 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m LOG_IT(("leto...\n")); - jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); - CHECK_RUNSTACK_OVERFLOW(); - mz_runstack_pushed(jitter, 1); + mz_runstack_skipped(jitter, 1); PAUSE_JIT_DATA(); generate_non_tail(lv->value, jitter, 0, 1); RESUME_JIT_DATA(); CHECK_LIMIT(); + + mz_runstack_unskipped(jitter, 1); + + jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); + CHECK_RUNSTACK_OVERFLOW(); + mz_runstack_pushed(jitter, 1); + jit_str_p(JIT_RUNSTACK, JIT_R0); END_JIT_DATA(17); @@ -5329,7 +5464,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m /* Key: */ generate_non_tail(wcm->key, jitter, 0, 1); CHECK_LIMIT(); - if (SCHEME_TYPE(obj) > _scheme_values_types_) { + if (SCHEME_TYPE(wcm->val) > _scheme_values_types_) { /* No need to push mark onto value stack: */ jit_movr_p(JIT_V1, JIT_R0); generate_non_tail(wcm->val, jitter, 0, 1); @@ -6596,7 +6731,9 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data) } } - LOG_IT(("PROC: %s\n", (data->name ? scheme_format_utf8("~s", 2, 1, &data->name, NULL) : "???"))); + LOG_IT(("PROC: %s, %d args\n", + (data->name ? scheme_format_utf8("~s", 2, 1, &data->name, NULL) : "???"), + data->num_params)); FOR_LOG(jitter->log_depth++); jitter->self_data = data; diff --git a/src/mzscheme/src/list.c b/src/mzscheme/src/list.c index 5e948b37b6..95a49dc3b4 100644 --- a/src/mzscheme/src/list.c +++ b/src/mzscheme/src/list.c @@ -155,19 +155,19 @@ scheme_init_list (Scheme_Env *env) SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; scheme_add_global_constant ("mcons", p, env); - p = scheme_make_noncm_prim(scheme_checked_mcar, "mcar", 1, 1); + p = scheme_make_immed_prim(scheme_checked_mcar, "mcar", 1, 1); SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED; scheme_add_global_constant ("mcar", p, env); - p = scheme_make_noncm_prim(scheme_checked_mcdr, "mcdr", 1, 1); + p = scheme_make_immed_prim(scheme_checked_mcdr, "mcdr", 1, 1); SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED; scheme_add_global_constant ("mcdr", p, env); - p = scheme_make_noncm_prim(scheme_checked_set_mcar, "set-mcar!", 2, 2); + p = scheme_make_immed_prim(scheme_checked_set_mcar, "set-mcar!", 2, 2); SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; scheme_add_global_constant ("set-mcar!", p, env); - p = scheme_make_noncm_prim(scheme_checked_set_mcdr, "set-mcdr!", 2, 2); + p = scheme_make_immed_prim(scheme_checked_set_mcdr, "set-mcdr!", 2, 2); SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; scheme_add_global_constant ("set-mcdr!", p, env); @@ -176,17 +176,17 @@ scheme_init_list (Scheme_Env *env) scheme_add_global_constant ("null?", p, env); scheme_add_global_constant ("list?", - scheme_make_noncm_prim(list_p_prim, + scheme_make_immed_prim(list_p_prim, "list?", 1, 1), env); scheme_add_global_constant ("list", - scheme_make_noncm_prim(list_prim, + scheme_make_immed_prim(list_prim, "list", 0, -1), env); scheme_add_global_constant ("list*", - scheme_make_noncm_prim(list_star_prim, + scheme_make_immed_prim(list_star_prim, "list*", 1, -1), env); @@ -196,57 +196,57 @@ scheme_init_list (Scheme_Env *env) 1, 1, 1), env); scheme_add_global_constant ("length", - scheme_make_noncm_prim(length_prim, + scheme_make_immed_prim(length_prim, "length", 1, 1), env); scheme_add_global_constant ("append", - scheme_make_noncm_prim(append_prim, + scheme_make_immed_prim(append_prim, "append", 0, -1), env); scheme_add_global_constant ("reverse", - scheme_make_noncm_prim(reverse_prim, + scheme_make_immed_prim(reverse_prim, "reverse", 1, 1), env); scheme_add_global_constant ("list-tail", - scheme_make_noncm_prim(list_tail_prim, + scheme_make_immed_prim(list_tail_prim, "list-tail", 2, 2), env); scheme_add_global_constant ("list-ref", - scheme_make_noncm_prim(list_ref_prim, + scheme_make_immed_prim(list_ref_prim, "list-ref", 2, 2), env); scheme_add_global_constant ("memq", - scheme_make_noncm_prim(memq, + scheme_make_immed_prim(memq, "memq", 2, 2), env); scheme_add_global_constant ("memv", - scheme_make_noncm_prim(memv, + scheme_make_immed_prim(memv, "memv", 2, 2), env); scheme_add_global_constant ("member", - scheme_make_noncm_prim(member, + scheme_make_immed_prim(member, "member", 2, 2), env); scheme_add_global_constant ("assq", - scheme_make_noncm_prim(assq, + scheme_make_immed_prim(assq, "assq", 2, 2), env); scheme_add_global_constant ("assv", - scheme_make_noncm_prim(assv, + scheme_make_immed_prim(assv, "assv", 2, 2), env); scheme_add_global_constant ("assoc", - scheme_make_noncm_prim(assoc, + scheme_make_immed_prim(assoc, "assoc", 2, 2), env); @@ -390,12 +390,12 @@ scheme_init_list (Scheme_Env *env) env); scheme_add_global_constant(BOX, - scheme_make_noncm_prim(box, + scheme_make_immed_prim(box, BOX, 1, 1), env); scheme_add_global_constant("box-immutable", - scheme_make_noncm_prim(immutable_box, + scheme_make_immed_prim(immutable_box, "box-immutable", 1, 1), env); @@ -404,23 +404,23 @@ scheme_init_list (Scheme_Env *env) SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED; scheme_add_global_constant(BOXP, p, env); - p = scheme_make_noncm_prim(unbox, UNBOX, 1, 1); + p = scheme_make_immed_prim(unbox, UNBOX, 1, 1); SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED; scheme_add_global_constant(UNBOX, p, env); scheme_add_global_constant(SETBOX, - scheme_make_noncm_prim(set_box, + scheme_make_immed_prim(set_box, SETBOX, 2, 2), env); scheme_add_global_constant("make-hash-table", - scheme_make_noncm_prim(make_hash_table, + scheme_make_immed_prim(make_hash_table, "make-hash-table", 0, 2), env); scheme_add_global_constant("make-immutable-hash-table", - scheme_make_noncm_prim(make_immutable_hash_table, + scheme_make_immed_prim(make_immutable_hash_table, "make-immutable-hash-table", 1, 2), env); @@ -430,7 +430,7 @@ scheme_init_list (Scheme_Env *env) 1, 3, 1), env); scheme_add_global_constant("hash-table-count", - scheme_make_noncm_prim(hash_table_count, + scheme_make_immed_prim(hash_table_count, "hash-table-count", 1, 1), env); @@ -466,28 +466,28 @@ scheme_init_list (Scheme_Env *env) env); scheme_add_global_constant("hash-table-iterate-first", - scheme_make_noncm_prim(hash_table_iterate_start, + scheme_make_immed_prim(hash_table_iterate_start, "hash-table-iterate-first", 1, 1), env); scheme_add_global_constant("hash-table-iterate-next", - scheme_make_noncm_prim(hash_table_iterate_next, + scheme_make_immed_prim(hash_table_iterate_next, "hash-table-iterate-next", 2, 2), env); scheme_add_global_constant("hash-table-iterate-value", - scheme_make_noncm_prim(hash_table_iterate_value, + scheme_make_immed_prim(hash_table_iterate_value, "hash-table-iterate-value", 2, 2), env); scheme_add_global_constant("hash-table-iterate-key", - scheme_make_noncm_prim(hash_table_iterate_key, + scheme_make_immed_prim(hash_table_iterate_key, "hash-table-iterate-key", 2, 2), env); scheme_add_global_constant("eq-hash-code", - scheme_make_noncm_prim(eq_hash_code, + scheme_make_immed_prim(eq_hash_code, "eq-hash-code", 1, 1), env); @@ -503,12 +503,12 @@ scheme_init_list (Scheme_Env *env) env); scheme_add_global_constant("make-weak-box", - scheme_make_noncm_prim(make_weak_box, + scheme_make_immed_prim(make_weak_box, "make-weak-box", 1, 1), env); scheme_add_global_constant("weak-box-value", - scheme_make_noncm_prim(weak_box_value, + scheme_make_immed_prim(weak_box_value, "weak-box-value", 1, 1), env); @@ -519,12 +519,12 @@ scheme_init_list (Scheme_Env *env) env); scheme_add_global_constant("make-ephemeron", - scheme_make_noncm_prim(make_ephemeron, + scheme_make_immed_prim(make_ephemeron, "make-ephemeron", 2, 2), env); scheme_add_global_constant("ephemeron-value", - scheme_make_noncm_prim(ephemeron_value, + scheme_make_immed_prim(ephemeron_value, "ephemeron-value", 1, 1), env); diff --git a/src/mzscheme/src/module.c b/src/mzscheme/src/module.c index 3f9b092f8c..4bc382f0a5 100644 --- a/src/mzscheme/src/module.c +++ b/src/mzscheme/src/module.c @@ -79,17 +79,21 @@ static Scheme_Object *top_level_require_jit(Scheme_Object *data); static Scheme_Object *module_optimize(Scheme_Object *data, Optimize_Info *info); static Scheme_Object *module_resolve(Scheme_Object *data, Resolve_Info *info); +static Scheme_Object *module_sfs(Scheme_Object *data, SFS_Info *info); static Scheme_Object *top_level_require_optimize(Scheme_Object *data, Optimize_Info *info); static Scheme_Object *top_level_require_resolve(Scheme_Object *data, Resolve_Info *info); +static Scheme_Object *top_level_require_sfs(Scheme_Object *data, SFS_Info *info); static void module_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts); + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos); static void top_level_require_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts); + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos); static Scheme_Object *write_module(Scheme_Object *obj); static Scheme_Object *read_module(Scheme_Object *obj); @@ -256,12 +260,12 @@ void scheme_init_module(Scheme_Env *env) scheme_register_syntax(MODULE_EXPD, module_optimize, - module_resolve, module_validate, + module_resolve, module_sfs, module_validate, module_execute, module_jit, NULL, NULL, -1); scheme_register_syntax(REQUIRE_EXPD, top_level_require_optimize, - top_level_require_resolve, top_level_require_validate, + top_level_require_resolve, top_level_require_sfs, top_level_require_validate, top_level_require_execute, top_level_require_jit, NULL, NULL, 2); @@ -4232,7 +4236,8 @@ static Scheme_Object *module_jit(Scheme_Object *data) static void module_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts) + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos) { Scheme_Module *m; int i, cnt, let_depth; @@ -4618,6 +4623,51 @@ module_resolve(Scheme_Object *data, Resolve_Info *old_rslv) return scheme_make_syntax_resolved(MODULE_EXPD, data); } +static Scheme_Object * +module_sfs(Scheme_Object *data, SFS_Info *old_info) +{ + Scheme_Module *m = (Scheme_Module *)data; + Scheme_Object *e, *ex; + SFS_Info *info; + int i, cnt, let_depth; + + if (!old_info->for_mod) { + if (old_info->pass) + return data; + + info = scheme_new_sfs_info(m->max_let_depth); + info->for_mod = 1; + scheme_sfs(data, info, m->max_let_depth); + return data; + } + + info = old_info; + + cnt = SCHEME_VEC_SIZE(m->body); + scheme_sfs_start_sequence(info, cnt, 0); + + for (i = 0; i < cnt; i++) { + e = scheme_sfs_expr(SCHEME_VEC_ELS(m->body)[i], info, -1); + SCHEME_VEC_ELS(m->body)[i] = e; + } + + if (!info->pass) { + cnt = SCHEME_VEC_SIZE(m->et_body); + for (i = 0; i < cnt; i++) { + e = SCHEME_VEC_ELS(m->et_body)[i]; + + let_depth = SCHEME_INT_VAL(SCHEME_VEC_ELS(e)[2]); + ex = SCHEME_VEC_ELS(e)[1]; + + info = scheme_new_sfs_info(let_depth); + ex = scheme_sfs(ex, info, let_depth); + SCHEME_VEC_ELS(e)[1] = ex; + } + } + + return data; +} + static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_Expand_Info *rec, int drec) { @@ -5561,6 +5611,7 @@ static Scheme_Object *do_module_begin(Scheme_Object *form, Scheme_Comp_Env *env, SCHEME_VEC_ELS(vec)[4] = (for_stx ? scheme_true : scheme_false); exp_body = scheme_make_pair(vec, exp_body); + m = scheme_sfs(m, NULL, ri->max_let_depth); if (ri->use_jit) m = scheme_jit_expr(m); @@ -8159,7 +8210,8 @@ top_level_require_jit(Scheme_Object *data) static void top_level_require_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts) + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos) { } @@ -8179,6 +8231,12 @@ top_level_require_resolve(Scheme_Object *data, Resolve_Info *rslv) return scheme_make_syntax_resolved(REQUIRE_EXPD, cons(dummy, SCHEME_CDR(data))); } +static Scheme_Object * +top_level_require_sfs(Scheme_Object *data, SFS_Info *rslv) +{ + return data; +} + static Scheme_Object *do_require(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_Expand_Info *rec, int drec) { diff --git a/src/mzscheme/src/mzmark.c b/src/mzscheme/src/mzmark.c index 36f1d424f9..192b872eb3 100644 --- a/src/mzscheme/src/mzmark.c +++ b/src/mzscheme/src/mzmark.c @@ -2788,6 +2788,36 @@ static int mark_optimize_info_FIXUP(void *p) { #define mark_optimize_info_IS_CONST_SIZE 1 +static int mark_sfs_info_SIZE(void *p) { + return + gcBYTES_TO_WORDS(sizeof(SFS_Info)); +} + +static int mark_sfs_info_MARK(void *p) { + SFS_Info *i = (SFS_Info *)p; + + gcMARK(i->max_used); + gcMARK(i->max_calls); + gcMARK(i->saved); + + return + gcBYTES_TO_WORDS(sizeof(SFS_Info)); +} + +static int mark_sfs_info_FIXUP(void *p) { + SFS_Info *i = (SFS_Info *)p; + + gcFIXUP(i->max_used); + gcFIXUP(i->max_calls); + gcFIXUP(i->saved); + + return + gcBYTES_TO_WORDS(sizeof(SFS_Info)); +} + +#define mark_sfs_info_IS_ATOMIC 0 +#define mark_sfs_info_IS_CONST_SIZE 1 + #endif /* ENV */ @@ -2855,6 +2885,35 @@ static int mark_saved_stack_FIXUP(void *p) { #define mark_saved_stack_IS_CONST_SIZE 1 +static int mark_validate_clearing_SIZE(void *p) { + return + gcBYTES_TO_WORDS(sizeof(Validate_Clearing)); +} + +static int mark_validate_clearing_MARK(void *p) { + Validate_Clearing *vc = (Validate_Clearing *)p; + + gcMARK(vc->stack); + gcMARK(vc->ncstack); + + return + gcBYTES_TO_WORDS(sizeof(Validate_Clearing)); +} + +static int mark_validate_clearing_FIXUP(void *p) { + Validate_Clearing *vc = (Validate_Clearing *)p; + + gcFIXUP(vc->stack); + gcFIXUP(vc->ncstack); + + return + gcBYTES_TO_WORDS(sizeof(Validate_Clearing)); +} + +#define mark_validate_clearing_IS_ATOMIC 0 +#define mark_validate_clearing_IS_CONST_SIZE 1 + + #endif /* EVAL */ /**********************************************************************/ diff --git a/src/mzscheme/src/mzmarksrc.c b/src/mzscheme/src/mzmarksrc.c index 7ae9bac768..82cbf9a08a 100644 --- a/src/mzscheme/src/mzmarksrc.c +++ b/src/mzscheme/src/mzmarksrc.c @@ -1115,6 +1115,17 @@ mark_optimize_info { gcBYTES_TO_WORDS(sizeof(Optimize_Info)); } +mark_sfs_info { + mark: + SFS_Info *i = (SFS_Info *)p; + + gcMARK(i->max_used); + gcMARK(i->max_calls); + gcMARK(i->saved); + + size: + gcBYTES_TO_WORDS(sizeof(SFS_Info)); +} END env; @@ -1145,6 +1156,17 @@ mark_saved_stack { gcBYTES_TO_WORDS(sizeof(Scheme_Saved_Stack)); } +mark_validate_clearing { + mark: + Validate_Clearing *vc = (Validate_Clearing *)p; + + gcMARK(vc->stack); + gcMARK(vc->ncstack); + + size: + gcBYTES_TO_WORDS(sizeof(Validate_Clearing)); +} + END eval; /**********************************************************************/ diff --git a/src/mzscheme/src/portfun.c b/src/mzscheme/src/portfun.c index cc3cb264e6..87a16cbe20 100644 --- a/src/mzscheme/src/portfun.c +++ b/src/mzscheme/src/portfun.c @@ -711,7 +711,7 @@ scheme_init_port_fun(Scheme_Env *env) 2, 2), env); scheme_add_global_constant("pipe-content-length", - scheme_make_noncm_prim(pipe_length, + scheme_make_immed_prim(pipe_length, "pipe-content-length", 1, 1), env); diff --git a/src/mzscheme/src/print.c b/src/mzscheme/src/print.c index 9448b7008d..4f6fbc8b1d 100644 --- a/src/mzscheme/src/print.c +++ b/src/mzscheme/src/print.c @@ -2272,15 +2272,22 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, { int unbox = SAME_TYPE(SCHEME_TYPE(obj), scheme_local_unbox_type); Scheme_Local *loc = (Scheme_Local *)obj; - if (loc->position < CPT_RANGE(SMALL_LOCAL)) { + if ((loc->position < CPT_RANGE(SMALL_LOCAL)) + && !(SCHEME_LOCAL_FLAGS(loc) & SCHEME_LOCAL_CLEARING_MASK)) { unsigned char s[1]; s[0] = loc->position + (unbox ? CPT_SMALL_LOCAL_UNBOX_START : CPT_SMALL_LOCAL_START); print_this_string(pp, (char *)s, 0, 1); } else { + int flags; print_compact(pp, unbox ? CPT_LOCAL_UNBOX : CPT_LOCAL); - print_compact_number(pp, loc->position); + flags = SCHEME_LOCAL_FLAGS(loc) & SCHEME_LOCAL_CLEARING_MASK; + if (flags) { + print_compact_number(pp, -(loc->position + 1)); + print_compact_number(pp, flags); + } else + print_compact_number(pp, loc->position); } } else if (compact && SAME_TYPE(SCHEME_TYPE(obj), scheme_application_type)) diff --git a/src/mzscheme/src/read.c b/src/mzscheme/src/read.c index 73a9de268d..6707dc37b2 100644 --- a/src/mzscheme/src/read.c +++ b/src/mzscheme/src/read.c @@ -4593,20 +4593,26 @@ static Scheme_Object *read_compact(CPort *port, int use_stack) break; case CPT_LOCAL: { - int p; + int p, flags; p = read_compact_number(port); - if (p < 0) - scheme_ill_formed_code(port); - v = scheme_make_local(scheme_local_type, p); + if (p < 0) { + p = -(p + 1); + flags = read_compact_number(port); + } else + flags = 0; + v = scheme_make_local(scheme_local_type, p, flags); } break; case CPT_LOCAL_UNBOX: { - int p; + int p, flags; p = read_compact_number(port); - if (p < 0) - scheme_ill_formed_code(port); - v = scheme_make_local(scheme_local_unbox_type, p); + if (p < 0) { + p = -(p + 1); + flags = read_compact_number(port); + } else + flags = 0; + v = scheme_make_local(scheme_local_unbox_type, p, flags); } break; case CPT_SVECTOR: @@ -4764,9 +4770,9 @@ static Scheme_Object *read_compact(CPort *port, int use_stack) ch -= CPT_SMALL_LOCAL_START; } if (ch < MAX_CONST_LOCAL_POS) - v = scheme_local[ch][k]; + v = scheme_local[ch][k][0]; else - v = scheme_make_local(type, ch); + v = scheme_make_local(type, ch, 0); } break; case CPT_SMALL_MARSHALLED_START: diff --git a/src/mzscheme/src/schemef.h b/src/mzscheme/src/schemef.h index 34869703d3..3bbb4138db 100644 --- a/src/mzscheme/src/schemef.h +++ b/src/mzscheme/src/schemef.h @@ -425,6 +425,9 @@ MZ_EXTERN Scheme_Object *scheme_make_folding_prim(Scheme_Prim *prim, const char *name, mzshort mina, mzshort maxa, short functional); +MZ_EXTERN Scheme_Object *scheme_make_immed_prim(Scheme_Prim *prim, + const char *name, + mzshort mina, mzshort maxa); MZ_EXTERN Scheme_Object *scheme_make_noncm_prim(Scheme_Prim *prim, const char *name, mzshort mina, mzshort maxa); diff --git a/src/mzscheme/src/schemex.h b/src/mzscheme/src/schemex.h index cf21f76e38..98902cd301 100644 --- a/src/mzscheme/src/schemex.h +++ b/src/mzscheme/src/schemex.h @@ -346,6 +346,9 @@ Scheme_Object *(*scheme_make_folding_prim)(Scheme_Prim *prim, const char *name, mzshort mina, mzshort maxa, short functional); +Scheme_Object *(*scheme_make_immed_prim)(Scheme_Prim *prim, + const char *name, + mzshort mina, mzshort maxa); Scheme_Object *(*scheme_make_noncm_prim)(Scheme_Prim *prim, const char *name, mzshort mina, mzshort maxa); diff --git a/src/mzscheme/src/schemex.inc b/src/mzscheme/src/schemex.inc index 000cd4e34c..18d973d7ad 100644 --- a/src/mzscheme/src/schemex.inc +++ b/src/mzscheme/src/schemex.inc @@ -236,6 +236,7 @@ scheme_extension_table->scheme_make_noneternal_prim = scheme_make_noneternal_prim; scheme_extension_table->scheme_make_prim_w_arity = scheme_make_prim_w_arity; scheme_extension_table->scheme_make_folding_prim = scheme_make_folding_prim; + scheme_extension_table->scheme_make_immed_prim = scheme_make_immed_prim; scheme_extension_table->scheme_make_noncm_prim = scheme_make_noncm_prim; scheme_extension_table->scheme_make_noneternal_prim_w_arity = scheme_make_noneternal_prim_w_arity; scheme_extension_table->scheme_make_prim_w_everything = scheme_make_prim_w_everything; diff --git a/src/mzscheme/src/schemexm.h b/src/mzscheme/src/schemexm.h index 352cc4deea..3f618c0b4f 100644 --- a/src/mzscheme/src/schemexm.h +++ b/src/mzscheme/src/schemexm.h @@ -236,6 +236,7 @@ #define scheme_make_noneternal_prim (scheme_extension_table->scheme_make_noneternal_prim) #define scheme_make_prim_w_arity (scheme_extension_table->scheme_make_prim_w_arity) #define scheme_make_folding_prim (scheme_extension_table->scheme_make_folding_prim) +#define scheme_make_immed_prim (scheme_extension_table->scheme_make_immed_prim) #define scheme_make_noncm_prim (scheme_extension_table->scheme_make_noncm_prim) #define scheme_make_noneternal_prim_w_arity (scheme_extension_table->scheme_make_noneternal_prim_w_arity) #define scheme_make_prim_w_everything (scheme_extension_table->scheme_make_prim_w_everything) diff --git a/src/mzscheme/src/schminc.h b/src/mzscheme/src/schminc.h index 75ec506e73..07a6c63afd 100644 --- a/src/mzscheme/src/schminc.h +++ b/src/mzscheme/src/schminc.h @@ -13,7 +13,7 @@ #define USE_COMPILED_STARTUP 1 -#define EXPECTED_PRIM_COUNT 892 +#define EXPECTED_PRIM_COUNT 893 #ifdef MZSCHEME_SOMETHING_OMITTED # undef USE_COMPILED_STARTUP diff --git a/src/mzscheme/src/schpriv.h b/src/mzscheme/src/schpriv.h index 1d6b5931aa..2b781a5a81 100644 --- a/src/mzscheme/src/schpriv.h +++ b/src/mzscheme/src/schpriv.h @@ -228,7 +228,7 @@ Scheme_Object *scheme_make_initial_inspectors(void); extern int scheme_builtin_ref_counter; Scheme_Object **scheme_make_builtin_references_table(void); -Scheme_Object *scheme_make_local(Scheme_Type type, int pos); +Scheme_Object *scheme_make_local(Scheme_Type type, int pos, int flags); void scheme_add_embedded_builtins(Scheme_Env *env); void scheme_do_add_global_symbol(Scheme_Env *env, Scheme_Object *sym, @@ -821,7 +821,7 @@ typedef struct { } Scheme_With_Continuation_Mark; typedef struct Scheme_Local { - Scheme_Object so; + Scheme_Inclhash_Object iso; /* keyex used for clear-on-read flag */ mzshort position; #ifdef MZ_PRECISE_GC # ifdef MZSHORT_IS_SHORT @@ -832,9 +832,14 @@ typedef struct Scheme_Local { } Scheme_Local; #define SCHEME_LOCAL_POS(obj) (((Scheme_Local *)(obj))->position) +#define SCHEME_LOCAL_FLAGS(obj) MZ_OPT_HASH_KEY(&((Scheme_Local *)(obj))->iso) + +#define SCHEME_LOCAL_CLEAR_ON_READ 0x1 +#define SCHEME_LOCAL_OTHER_CLEARS 0x2 +#define SCHEME_LOCAL_CLEARING_MASK 0x3 typedef struct Scheme_Toplevel { - Scheme_Inclhash_Object iso; /* keyex used for const flag */ + Scheme_Inclhash_Object iso; /* keyex used for const & ready flags */ mzshort depth; int position; } Scheme_Toplevel; @@ -1689,7 +1694,7 @@ typedef struct Scheme_Comp_Env #define CLOS_HAS_REST 1 #define CLOS_HAS_REF_ARGS 2 #define CLOS_PRESERVES_MARKS 4 -#define CLOS_FOLDABLE 8 +#define CLOS_SFS 8 #define CLOS_IS_METHOD 16 #define CLOS_SINGLE_RESULT 32 #define CLOS_RESULT_TENTATIVE 64 @@ -1784,11 +1789,13 @@ typedef struct Scheme_Object *(*Scheme_Syntax_Shifter)(Scheme_Object *data, int typedef struct CPort Mz_CPort; typedef mzshort **Validate_TLS; +struct Validate_Clearing; typedef void (*Scheme_Syntax_Validater)(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts); + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos); typedef struct Scheme_Object *(*Scheme_Syntax_Executer)(struct Scheme_Object *data); @@ -1859,7 +1866,7 @@ Scheme_Native_Closure_Data *scheme_generate_lambda(Scheme_Closure_Data *obj, int Scheme_Native_Closure_Data *case_lam); #define MAX_CONST_LOCAL_POS 64 -extern Scheme_Object *scheme_local[MAX_CONST_LOCAL_POS][2]; +extern Scheme_Object *scheme_local[MAX_CONST_LOCAL_POS][2][3]; #define scheme_new_frame(n) scheme_new_special_frame(n, 0) #define scheme_extend_env(f, e) (f->basic.next = e, f) @@ -1949,6 +1956,31 @@ void scheme_bind_syntaxes(const char *where, Scheme_Object *names, Scheme_Object int *_pos); int scheme_is_sub_env(Scheme_Comp_Env *stx_env, Scheme_Comp_Env *env); +typedef struct SFS_Info { + MZTAG_IF_REQUIRED + int for_mod, pass; + int tail_pos; + int depth, stackpos, tlpos; + int selfpos, selfstart, selflen; + int ip, seqn, max_nontail; + int min_touch, max_touch; + int *max_used, *max_calls; + Scheme_Object *saved; +} SFS_Info; + +SFS_Info *scheme_new_sfs_info(int depth); +Scheme_Object *scheme_sfs(Scheme_Object *expr, SFS_Info *info, int max_let_depth); +Scheme_Object *scheme_sfs_expr(Scheme_Object *expr, SFS_Info *si, int self_pos); +Scheme_Object *scheme_sfs_closure(Scheme_Object *expr, SFS_Info *si, int self_pos); + +void scheme_sfs_used(SFS_Info *info, int pos); +void scheme_sfs_push(SFS_Info *info, int count, int track); +void scheme_sfs_start_sequence(SFS_Info *si, int cnt, int last_is_tail); + +Scheme_Object *scheme_sfs_add_clears(Scheme_Object *expr, Scheme_Object *clears, int pre); + +typedef struct Scheme_Object *(*Scheme_Syntax_SFSer)(Scheme_Object *data, SFS_Info *info); + /* Resolving & linking */ #define DEFINE_VALUES_EXPD 0 #define DEFINE_SYNTAX_EXPD 1 @@ -1964,10 +1996,11 @@ int scheme_is_sub_env(Scheme_Comp_Env *stx_env, Scheme_Comp_Env *env); #define SPLICE_EXPD 11 #define _COUNT_EXPD_ 12 -#define scheme_register_syntax(i, fo, fr, fv, fe, fj, cl, sh, pa) \ +#define scheme_register_syntax(i, fo, fr, fs, fv, fe, fj, cl, sh, pa) \ (scheme_syntax_optimizers[i] = fo, \ scheme_syntax_resolvers[i] = fr, \ scheme_syntax_executers[i] = fe, \ + scheme_syntax_sfsers[i] = fs, \ scheme_syntax_validaters[i] = fv, \ scheme_syntax_jitters[i] = fj, \ scheme_syntax_cloners[i] = cl, \ @@ -1975,6 +2008,7 @@ int scheme_is_sub_env(Scheme_Comp_Env *stx_env, Scheme_Comp_Env *env); scheme_syntax_protect_afters[i] = pa) extern Scheme_Syntax_Optimizer scheme_syntax_optimizers[_COUNT_EXPD_]; extern Scheme_Syntax_Resolver scheme_syntax_resolvers[_COUNT_EXPD_]; +extern Scheme_Syntax_SFSer scheme_syntax_sfsers[_COUNT_EXPD_]; extern Scheme_Syntax_Validater scheme_syntax_validaters[_COUNT_EXPD_]; extern Scheme_Syntax_Executer scheme_syntax_executers[_COUNT_EXPD_]; extern Scheme_Syntax_Jitter scheme_syntax_jitters[_COUNT_EXPD_]; @@ -2228,7 +2262,8 @@ void scheme_validate_expr(Mz_CPort *port, Scheme_Object *expr, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, int num_toplevels, int num_stxes, int num_lifts, - Scheme_Object *app_rator, int proc_with_refs_ok); + Scheme_Object *app_rator, int proc_with_refs_ok, + int result_ignored, struct Validate_Clearing *vc, int tailpos); void scheme_validate_toplevel(Scheme_Object *expr, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int delta, @@ -2244,7 +2279,8 @@ int scheme_validate_rator_wants_box(Scheme_Object *app_rator, int pos, void scheme_validate_closure(Mz_CPort *port, Scheme_Object *expr, char *new_stack, Validate_TLS tls, - int num_toplevels, int num_stxes, int num_lifts); + int num_toplevels, int num_stxes, int num_lifts, + int self_pos_in_closure); #define TRACK_ILL_FORMED_CATCH_LINES 1 #if TRACK_ILL_FORMED_CATCH_LINES @@ -2568,6 +2604,9 @@ long scheme_extract_index(const char *name, int pos, int argc, void scheme_get_substring_indices(const char *name, Scheme_Object *str, int argc, Scheme_Object **argv, int spos, int fpos, long *_start, long *_finish); +void scheme_do_get_substring_indices(const char *name, Scheme_Object *str, + int argc, Scheme_Object **argv, + int spos, int fpos, long *_start, long *_finish, long len); void scheme_out_of_string_range(const char *name, const char *which, Scheme_Object *i, Scheme_Object *s, diff --git a/src/mzscheme/src/schvers.h b/src/mzscheme/src/schvers.h index e79aa107a0..0b4ebd3eb5 100644 --- a/src/mzscheme/src/schvers.h +++ b/src/mzscheme/src/schvers.h @@ -10,12 +10,12 @@ The string and the separate X/Y/Z/W numbers must be updated consistently. */ -#define MZSCHEME_VERSION "3.99.0.10" +#define MZSCHEME_VERSION "3.99.0.11" #define MZSCHEME_VERSION_X 3 #define MZSCHEME_VERSION_Y 99 #define MZSCHEME_VERSION_Z 0 -#define MZSCHEME_VERSION_W 10 +#define MZSCHEME_VERSION_W 11 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) diff --git a/src/mzscheme/src/string.c b/src/mzscheme/src/string.c index ee9b64f89a..ba067c5e41 100644 --- a/src/mzscheme/src/string.c +++ b/src/mzscheme/src/string.c @@ -387,12 +387,12 @@ scheme_init_string (Scheme_Env *env) scheme_add_global_constant("string?", p, env); scheme_add_global_constant("make-string", - scheme_make_noncm_prim(make_string, + scheme_make_immed_prim(make_string, "make-string", 1, 2), env); scheme_add_global_constant("string", - scheme_make_noncm_prim(string, + scheme_make_immed_prim(string, "string", 0, -1), env); @@ -402,185 +402,185 @@ scheme_init_string (Scheme_Env *env) 1, 1, 1), env); - p = scheme_make_noncm_prim(scheme_checked_string_ref, "string-ref", 2, 2); + p = scheme_make_immed_prim(scheme_checked_string_ref, "string-ref", 2, 2); SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; scheme_add_global_constant("string-ref", p, env); - p = scheme_make_noncm_prim(scheme_checked_string_set, "string-set!", 3, 3); + p = scheme_make_immed_prim(scheme_checked_string_set, "string-set!", 3, 3); SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_MIN_NARY_INLINED; scheme_add_global_constant("string-set!", p, env); scheme_add_global_constant("string=?", - scheme_make_noncm_prim(string_eq, + scheme_make_immed_prim(string_eq, "string=?", 2, -1), env); scheme_add_global_constant("string-locale=?", - scheme_make_noncm_prim(string_locale_eq, + scheme_make_immed_prim(string_locale_eq, "string-locale=?", 2, -1), env); scheme_add_global_constant("string-ci=?", - scheme_make_noncm_prim(string_ci_eq, + scheme_make_immed_prim(string_ci_eq, "string-ci=?", 2, -1), env); scheme_add_global_constant("string-locale-ci=?", - scheme_make_noncm_prim(string_locale_ci_eq, + scheme_make_immed_prim(string_locale_ci_eq, "string-locale-ci=?", 2, -1), env); scheme_add_global_constant("string?", - scheme_make_noncm_prim(string_gt, + scheme_make_immed_prim(string_gt, "string>?", 2, -1), env); scheme_add_global_constant("string-locale>?", - scheme_make_noncm_prim(string_locale_gt, + scheme_make_immed_prim(string_locale_gt, "string-locale>?", 2, -1), env); scheme_add_global_constant("string<=?", - scheme_make_noncm_prim(string_lt_eq, + scheme_make_immed_prim(string_lt_eq, "string<=?", 2, -1), env); scheme_add_global_constant("string>=?", - scheme_make_noncm_prim(string_gt_eq, + scheme_make_immed_prim(string_gt_eq, "string>=?", 2, -1), env); scheme_add_global_constant("string-ci?", - scheme_make_noncm_prim(string_ci_gt, + scheme_make_immed_prim(string_ci_gt, "string-ci>?", 2, -1), env); scheme_add_global_constant("string-locale-ci>?", - scheme_make_noncm_prim(string_locale_ci_gt, + scheme_make_immed_prim(string_locale_ci_gt, "string-locale-ci>?", 2, -1), env); scheme_add_global_constant("string-ci<=?", - scheme_make_noncm_prim(string_ci_lt_eq, + scheme_make_immed_prim(string_ci_lt_eq, "string-ci<=?", 2, -1), env); scheme_add_global_constant("string-ci>=?", - scheme_make_noncm_prim(string_ci_gt_eq, + scheme_make_immed_prim(string_ci_gt_eq, "string-ci>=?", 2, -1), env); scheme_add_global_constant("substring", - scheme_make_noncm_prim(substring, + scheme_make_immed_prim(substring, "substring", 2, 3), env); scheme_add_global_constant("string-append", - scheme_make_noncm_prim(string_append, + scheme_make_immed_prim(string_append, "string-append", 0, -1), env); scheme_add_global_constant("string->list", - scheme_make_noncm_prim(string_to_list, + scheme_make_immed_prim(string_to_list, "string->list", 1, 1), env); scheme_add_global_constant("list->string", - scheme_make_noncm_prim(list_to_string, + scheme_make_immed_prim(list_to_string, "list->string", 1, 1), env); scheme_add_global_constant("string-copy", - scheme_make_noncm_prim(string_copy, + scheme_make_immed_prim(string_copy, "string-copy", 1, 1), env); scheme_add_global_constant("string-copy!", - scheme_make_noncm_prim(string_copy_bang, + scheme_make_immed_prim(string_copy_bang, "string-copy!", 3, 5), env); scheme_add_global_constant("string-fill!", - scheme_make_noncm_prim(string_fill, + scheme_make_immed_prim(string_fill, "string-fill!", 2, 2), env); scheme_add_global_constant("string->immutable-string", - scheme_make_noncm_prim(string_to_immutable, + scheme_make_immed_prim(string_to_immutable, "string->immutable-string", 1, 1), env); scheme_add_global_constant("string-normalize-nfc", - scheme_make_noncm_prim(string_normalize_c, + scheme_make_immed_prim(string_normalize_c, "string-normalize-nfc", 1, 1), env); scheme_add_global_constant("string-normalize-nfkc", - scheme_make_noncm_prim(string_normalize_kc, + scheme_make_immed_prim(string_normalize_kc, "string-normalize-nfkc", 1, 1), env); scheme_add_global_constant("string-normalize-nfd", - scheme_make_noncm_prim(string_normalize_d, + scheme_make_immed_prim(string_normalize_d, "string-normalize-nfd", 1, 1), env); scheme_add_global_constant("string-normalize-nfkd", - scheme_make_noncm_prim(string_normalize_kd, + scheme_make_immed_prim(string_normalize_kd, "string-normalize-nfkd", 1, 1), env); scheme_add_global_constant("string-upcase", - scheme_make_noncm_prim(string_upcase, + scheme_make_immed_prim(string_upcase, "string-upcase", 1, 1), env); scheme_add_global_constant("string-downcase", - scheme_make_noncm_prim(string_downcase, + scheme_make_immed_prim(string_downcase, "string-downcase", 1, 1), env); scheme_add_global_constant("string-titlecase", - scheme_make_noncm_prim(string_titlecase, + scheme_make_immed_prim(string_titlecase, "string-titlecase", 1, 1), env); scheme_add_global_constant("string-foldcase", - scheme_make_noncm_prim(string_foldcase, + scheme_make_immed_prim(string_foldcase, "string-foldcase", 1, 1), env); scheme_add_global_constant("string-locale-upcase", - scheme_make_noncm_prim(string_locale_upcase, + scheme_make_immed_prim(string_locale_upcase, "string-locale-upcase", 1, 1), env); scheme_add_global_constant("string-locale-downcase", - scheme_make_noncm_prim(string_locale_downcase, + scheme_make_immed_prim(string_locale_downcase, "string-locale-downcase", 1, 1), env); @@ -591,18 +591,18 @@ scheme_init_string (Scheme_Env *env) MZCONFIG_LOCALE), env); scheme_add_global_constant("locale-string-encoding", - scheme_make_noncm_prim(locale_string_encoding, + scheme_make_immed_prim(locale_string_encoding, "locale-string-encoding", 0, 0), env); scheme_add_global_constant("system-language+country", - scheme_make_noncm_prim(system_language_country, + scheme_make_immed_prim(system_language_country, "system-language+country", 0, 0), env); scheme_add_global_constant("bytes-converter?", - scheme_make_noncm_prim(byte_converter_p, + scheme_make_immed_prim(byte_converter_p, "bytes-converter?", 1, 1), env); @@ -619,12 +619,12 @@ scheme_init_string (Scheme_Env *env) 2, 2), env); scheme_add_global_constant("bytes-open-converter", - scheme_make_noncm_prim(byte_string_open_converter, + scheme_make_immed_prim(byte_string_open_converter, "bytes-open-converter", 2, 2), env); scheme_add_global_constant("bytes-close-converter", - scheme_make_noncm_prim(byte_string_close_converter, + scheme_make_immed_prim(byte_string_close_converter, "bytes-close-converter", 1, 1), env); @@ -656,12 +656,12 @@ scheme_init_string (Scheme_Env *env) scheme_add_global_constant("bytes?", p, env); scheme_add_global_constant("make-bytes", - scheme_make_noncm_prim(make_byte_string, + scheme_make_immed_prim(make_byte_string, "make-bytes", 1, 2), env); scheme_add_global_constant("bytes", - scheme_make_noncm_prim(byte_string, + scheme_make_immed_prim(byte_string, "bytes", 0, -1), env); @@ -671,121 +671,121 @@ scheme_init_string (Scheme_Env *env) 1, 1, 1), env); - p = scheme_make_noncm_prim(scheme_checked_byte_string_ref, "bytes-ref", 2, 2); + p = scheme_make_immed_prim(scheme_checked_byte_string_ref, "bytes-ref", 2, 2); SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; scheme_add_global_constant("bytes-ref", p, env); - p = scheme_make_noncm_prim(scheme_checked_byte_string_set, "bytes-set!", 3, 3); + p = scheme_make_immed_prim(scheme_checked_byte_string_set, "bytes-set!", 3, 3); SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_MIN_NARY_INLINED; scheme_add_global_constant("bytes-set!", p, env); scheme_add_global_constant("bytes=?", - scheme_make_noncm_prim(byte_string_eq, + scheme_make_immed_prim(byte_string_eq, "bytes=?", 2, -1), env); scheme_add_global_constant("bytes?", - scheme_make_noncm_prim(byte_string_gt, + scheme_make_immed_prim(byte_string_gt, "bytes>?", 2, -1), env); scheme_add_global_constant("subbytes", - scheme_make_noncm_prim(byte_substring, + scheme_make_immed_prim(byte_substring, "subbytes", 2, 3), env); scheme_add_global_constant("bytes-append", - scheme_make_noncm_prim(byte_string_append, + scheme_make_immed_prim(byte_string_append, "bytes-append", 0, -1), env); scheme_add_global_constant("bytes->list", - scheme_make_noncm_prim(byte_string_to_list, + scheme_make_immed_prim(byte_string_to_list, "bytes->list", 1, 1), env); scheme_add_global_constant("list->bytes", - scheme_make_noncm_prim(list_to_byte_string, + scheme_make_immed_prim(list_to_byte_string, "list->bytes", 1, 1), env); scheme_add_global_constant("bytes-copy", - scheme_make_noncm_prim(byte_string_copy, + scheme_make_immed_prim(byte_string_copy, "bytes-copy", 1, 1), env); scheme_add_global_constant("bytes-copy!", - scheme_make_noncm_prim(byte_string_copy_bang, + scheme_make_immed_prim(byte_string_copy_bang, "bytes-copy!", 3, 5), env); scheme_add_global_constant("bytes-fill!", - scheme_make_noncm_prim(byte_string_fill, + scheme_make_immed_prim(byte_string_fill, "bytes-fill!", 2, 2), env); scheme_add_global_constant("bytes->immutable-bytes", - scheme_make_noncm_prim(byte_string_to_immutable, + scheme_make_immed_prim(byte_string_to_immutable, "bytes->immutable-bytes", 1, 1), env); scheme_add_global_constant("bytes-utf-8-index", - scheme_make_noncm_prim(byte_string_utf8_index, + scheme_make_immed_prim(byte_string_utf8_index, "bytes-utf-8-index", 2, 4), env); scheme_add_global_constant("bytes-utf-8-length", - scheme_make_noncm_prim(byte_string_utf8_length, + scheme_make_immed_prim(byte_string_utf8_length, "bytes-utf-8-length", 1, 4), env); scheme_add_global_constant("bytes-utf-8-ref", - scheme_make_noncm_prim(byte_string_utf8_ref, + scheme_make_immed_prim(byte_string_utf8_ref, "bytes-utf-8-ref", 2, 4), env); scheme_add_global_constant("bytes->string/utf-8", - scheme_make_noncm_prim(byte_string_to_char_string, + scheme_make_immed_prim(byte_string_to_char_string, "bytes->string/utf-8", 1, 4), env); scheme_add_global_constant("bytes->string/locale", - scheme_make_noncm_prim(byte_string_to_char_string_locale, + scheme_make_immed_prim(byte_string_to_char_string_locale, "bytes->string/locale", 1, 4), env); scheme_add_global_constant("bytes->string/latin-1", - scheme_make_noncm_prim(byte_string_to_char_string_latin1, + scheme_make_immed_prim(byte_string_to_char_string_latin1, "bytes->string/latin-1", 1, 4), env); scheme_add_global_constant("string->bytes/utf-8", - scheme_make_noncm_prim(char_string_to_byte_string, + scheme_make_immed_prim(char_string_to_byte_string, "string->bytes/utf-8", 1, 4), env); scheme_add_global_constant("string->bytes/locale", - scheme_make_noncm_prim(char_string_to_byte_string_locale, + scheme_make_immed_prim(char_string_to_byte_string_locale, "string->bytes/locale", 1, 4), env); scheme_add_global_constant("string->bytes/latin-1", - scheme_make_noncm_prim(char_string_to_byte_string_latin1, + scheme_make_immed_prim(char_string_to_byte_string_latin1, "string->bytes/latin-1", 1, 4), env); scheme_add_global_constant("string-utf-8-length", - scheme_make_noncm_prim(char_string_utf8_length, + scheme_make_immed_prim(char_string_utf8_length, "string-utf-8-length", 1, 3), env); @@ -795,23 +795,23 @@ scheme_init_string (Scheme_Env *env) more problems than it solves... */ scheme_add_global_constant("version", - scheme_make_noncm_prim(version, + scheme_make_immed_prim(version, "version", 0, 0), env); scheme_add_global_constant("banner", - scheme_make_noncm_prim(banner, + scheme_make_immed_prim(banner, "banner", 0, 0), env); scheme_add_global_constant("getenv", - scheme_make_noncm_prim(sch_getenv, + scheme_make_immed_prim(sch_getenv, "getenv", 1, 1), env); scheme_add_global_constant("putenv", - scheme_make_noncm_prim(sch_putenv, + scheme_make_immed_prim(sch_putenv, "putenv", 2, 2), env); @@ -819,12 +819,12 @@ scheme_init_string (Scheme_Env *env) /* Don't make these folding, since they're platform-specific: */ scheme_add_global_constant("system-type", - scheme_make_noncm_prim(system_type, + scheme_make_immed_prim(system_type, "system-type", 0, 1), env); scheme_add_global_constant("system-library-subpath", - scheme_make_noncm_prim(system_library_subpath, + scheme_make_immed_prim(system_library_subpath, "system-library-subpath", 0, 1), env); @@ -908,24 +908,26 @@ void scheme_out_of_string_range(const char *name, const char *which, is_byte = SCHEME_BYTE_STRINGP(s); - if ((is_byte ? SCHEME_BYTE_STRTAG_VAL(s) : SCHEME_CHAR_STRTAG_VAL(s))) { + if (len) { char *sstr; int slen; sstr = scheme_make_provided_string(s, 2, &slen); scheme_raise_exn(MZEXN_FAIL_CONTRACT, - "%s: %sindex %s out of range [%d, %d] for %sstring: %t", + "%s: %sindex %s out of range [%d, %d] for %s%s: %t", name, which, scheme_make_provided_string(i, 2, NULL), start, len, is_byte ? "byte-" : "", + SCHEME_VECTORP(s) ? "vector" : "string", sstr, slen); } else { scheme_raise_exn(MZEXN_FAIL_CONTRACT, - "%s: %sindex %s out of range for empty %sstring", + "%s: %sindex %s out of range for empty %s%s", name, which, scheme_make_provided_string(i, 0, NULL), - is_byte ? "byte-" : ""); + is_byte ? "byte-" : "", + SCHEME_VECTORP(s) ? "vector" : "string"); } } @@ -960,6 +962,8 @@ void scheme_get_substring_indices(const char *name, Scheme_Object *str, long len; long start, finish; + if (SCHEME_VECTORP(str)) + len = SCHEME_VEC_SIZE(str); if (SCHEME_CHAR_STRINGP(str)) len = SCHEME_CHAR_STRTAG_VAL(str); else @@ -985,9 +989,9 @@ void scheme_get_substring_indices(const char *name, Scheme_Object *str, *_finish = finish; } -static void get_substring_indices(const char *name, Scheme_Object *str, - int argc, Scheme_Object **argv, - int spos, int fpos, long *_start, long *_finish, long len) +void scheme_do_get_substring_indices(const char *name, Scheme_Object *str, + int argc, Scheme_Object **argv, + int spos, int fpos, long *_start, long *_finish, long len) { if (argc > spos) { if (SCHEME_INTP(argv[spos])) { diff --git a/src/mzscheme/src/strops.inc b/src/mzscheme/src/strops.inc index fa17e80a83..74c668f7bb 100644 --- a/src/mzscheme/src/strops.inc +++ b/src/mzscheme/src/strops.inc @@ -208,8 +208,8 @@ X__(substring) (int argc, Scheme_Object *argv[]) chars = SCHEME_X_STR_VAL(argv[0]); - get_substring_indices(SUBXSTR, argv[0], argc, argv, 1, 2, - &start, &finish, SCHEME_X_STRTAG_VAL(argv[0])); + scheme_do_get_substring_indices(SUBXSTR, argv[0], argc, argv, 1, 2, + &start, &finish, SCHEME_X_STRTAG_VAL(argv[0])); str = X(scheme_alloc, _string)(finish-start, 0); memcpy(SCHEME_X_STR_VAL(str), chars + start, (finish - start) * sizeof(Xchar)); @@ -349,18 +349,18 @@ X__(string_copy_bang)(int argc, Scheme_Object *argv[]) if (!SCHEME_MUTABLE_X_STRINGP(s1)) scheme_wrong_type(XSTRINGSTR "-copy!", "mutable " XSTR "string", 0, argc, argv); - get_substring_indices(XSTRINGSTR "-copy!", s1, - argc, argv, 1, 5, - &ostart, &ofinish, SCHEME_X_STRTAG_VAL(s1)); + scheme_do_get_substring_indices(XSTRINGSTR "-copy!", s1, + argc, argv, 1, 5, + &ostart, &ofinish, SCHEME_X_STRTAG_VAL(s1)); s2 = argv[2]; if (!SCHEME_X_STRINGP(s2)) scheme_wrong_type(XSTRINGSTR "-copy!", XSTR "string", 2, argc, argv); - get_substring_indices(XSTRINGSTR "-copy!", s2, - argc, argv, 3, 4, - &istart, &ifinish, SCHEME_X_STRTAG_VAL(s2)); - + scheme_do_get_substring_indices(XSTRINGSTR "-copy!", s2, + argc, argv, 3, 4, + &istart, &ifinish, SCHEME_X_STRTAG_VAL(s2)); + if ((ofinish - ostart) < (ifinish - istart)) { scheme_arg_mismatch(XSTRINGSTR "-copy!", "not enough room in target " XSTR "string: ", diff --git a/src/mzscheme/src/struct.c b/src/mzscheme/src/struct.c index e081589aae..2d7bcd89e7 100644 --- a/src/mzscheme/src/struct.c +++ b/src/mzscheme/src/struct.c @@ -2300,7 +2300,7 @@ make_struct_proc(Scheme_Struct_Type *struct_type, p = scheme_make_folding_prim_closure(struct_getter, 1, a, func_name, - 1 + need_pos, 1 + need_pos, 1); + 1 + need_pos, 1 + need_pos, 0); if (need_pos) flags |= SCHEME_PRIM_STRUCT_TYPE_INDEXLESS_GETTER | SCHEME_PRIM_IS_STRUCT_OTHER; else diff --git a/src/mzscheme/src/stxobj.c b/src/mzscheme/src/stxobj.c index 37e66ffa05..c315eea4c5 100644 --- a/src/mzscheme/src/stxobj.c +++ b/src/mzscheme/src/stxobj.c @@ -400,70 +400,70 @@ void scheme_init_stx(Scheme_Env *env) env); scheme_add_global_constant("syntax-original?", - scheme_make_noncm_prim(syntax_original_p, + scheme_make_immed_prim(syntax_original_p, "syntax-original?", 1, 1), env); scheme_add_global_constant("syntax-property", - scheme_make_noncm_prim(syntax_property, + scheme_make_immed_prim(syntax_property, "syntax-property", 2, 3), env); scheme_add_global_constant("syntax-property-symbol-keys", - scheme_make_noncm_prim(syntax_property_keys, + scheme_make_immed_prim(syntax_property_keys, "syntax-property-symbol-keys", 1, 1), env); scheme_add_global_constant("syntax-track-origin", - scheme_make_noncm_prim(syntax_track_origin, + scheme_make_immed_prim(syntax_track_origin, "syntax-track-origin", 3, 3), env); scheme_add_global_constant("bound-identifier=?", - scheme_make_noncm_prim(bound_eq, + scheme_make_immed_prim(bound_eq, "bound-identifier=?", 2, 2), env); scheme_add_global_constant("free-identifier=?", - scheme_make_noncm_prim(module_eq, + scheme_make_immed_prim(module_eq, "free-identifier=?", 2, 2), env); scheme_add_global_constant("free-transformer-identifier=?", - scheme_make_noncm_prim(module_trans_eq, + scheme_make_immed_prim(module_trans_eq, "free-transformer-identifier=?", 2, 2), env); scheme_add_global_constant("free-template-identifier=?", - scheme_make_noncm_prim(module_templ_eq, + scheme_make_immed_prim(module_templ_eq, "free-template-identifier=?", 2, 2), env); scheme_add_global_constant("free-label-identifier=?", - scheme_make_noncm_prim(module_label_eq, + scheme_make_immed_prim(module_label_eq, "free-label-identifier=?", 2, 2), env); scheme_add_global_constant("identifier-binding", - scheme_make_noncm_prim(module_binding, + scheme_make_immed_prim(module_binding, "identifier-binding", 1, 1), env); scheme_add_global_constant("identifier-transformer-binding", - scheme_make_noncm_prim(module_trans_binding, + scheme_make_immed_prim(module_trans_binding, "identifier-transformer-binding", 1, 2), env); scheme_add_global_constant("identifier-template-binding", - scheme_make_noncm_prim(module_templ_binding, + scheme_make_immed_prim(module_templ_binding, "identifier-template-binding", 1, 1), env); scheme_add_global_constant("identifier-label-binding", - scheme_make_noncm_prim(module_label_binding, + scheme_make_immed_prim(module_label_binding, "identifier-label-binding", 1, 1), env); @@ -476,7 +476,7 @@ void scheme_init_stx(Scheme_Env *env) env); scheme_add_global_constant("syntax-recertify", - scheme_make_noncm_prim(syntax_recertify, + scheme_make_immed_prim(syntax_recertify, "syntax-recertify", 4, 4), env); diff --git a/src/mzscheme/src/stypes.h b/src/mzscheme/src/stypes.h index 87d97edb7c..8008657cba 100644 --- a/src/mzscheme/src/stypes.h +++ b/src/mzscheme/src/stypes.h @@ -235,6 +235,8 @@ enum { scheme_rt_marshal_info, /* 213 */ scheme_rt_unmarshal_info, /* 214 */ scheme_rt_runstack, /* 215 */ + scheme_rt_sfs_info, /* 216 */ + scheme_rt_validate_clearing, /* 217 */ #endif _scheme_last_type_ diff --git a/src/mzscheme/src/symbol.c b/src/mzscheme/src/symbol.c index 8446dce184..2b9217e0bd 100644 --- a/src/mzscheme/src/symbol.c +++ b/src/mzscheme/src/symbol.c @@ -302,16 +302,16 @@ scheme_init_symbol (Scheme_Env *env) scheme_add_global_constant("symbol?", p, env); scheme_add_global_constant("string->symbol", - scheme_make_noncm_prim(string_to_symbol_prim, + scheme_make_immed_prim(string_to_symbol_prim, "string->symbol", 1, 1), env); scheme_add_global_constant("string->uninterned-symbol", - scheme_make_noncm_prim(string_to_uninterned_symbol_prim, + scheme_make_immed_prim(string_to_uninterned_symbol_prim, "string->uninterned-symbol", 1, 1), env); scheme_add_global_constant("symbol->string", - scheme_make_noncm_prim(symbol_to_string_prim, + scheme_make_immed_prim(symbol_to_string_prim, "symbol->string", 1, 1), env); @@ -327,17 +327,17 @@ scheme_init_symbol (Scheme_Env *env) 2, -1, 1), env); scheme_add_global_constant("string->keyword", - scheme_make_noncm_prim(string_to_keyword_prim, + scheme_make_immed_prim(string_to_keyword_prim, "string->keyword", 1, 1), env); scheme_add_global_constant("keyword->string", - scheme_make_noncm_prim(keyword_to_string_prim, + scheme_make_immed_prim(keyword_to_string_prim, "keyword->string", 1, 1), env); scheme_add_global_constant("gensym", - scheme_make_noncm_prim(gensym, + scheme_make_immed_prim(gensym, "gensym", 0, 1), env); diff --git a/src/mzscheme/src/syntax.c b/src/mzscheme/src/syntax.c index c74c01b6f5..98f80086c3 100644 --- a/src/mzscheme/src/syntax.c +++ b/src/mzscheme/src/syntax.c @@ -43,6 +43,7 @@ Scheme_Object scheme_undefined[1]; Scheme_Syntax_Optimizer scheme_syntax_optimizers[_COUNT_EXPD_]; Scheme_Syntax_Resolver scheme_syntax_resolvers[_COUNT_EXPD_]; +Scheme_Syntax_SFSer scheme_syntax_sfsers[_COUNT_EXPD_]; Scheme_Syntax_Validater scheme_syntax_validaters[_COUNT_EXPD_]; Scheme_Syntax_Executer scheme_syntax_executers[_COUNT_EXPD_]; Scheme_Syntax_Jitter scheme_syntax_jitters[_COUNT_EXPD_]; @@ -137,46 +138,67 @@ static Scheme_Object *begin0_resolve(Scheme_Object *data, Resolve_Info *info); static Scheme_Object *apply_values_resolve(Scheme_Object *data, Resolve_Info *info); static Scheme_Object *splice_resolve(Scheme_Object *data, Resolve_Info *info); +static Scheme_Object *define_values_sfs(Scheme_Object *data, SFS_Info *info); +static Scheme_Object *ref_sfs(Scheme_Object *data, SFS_Info *info); +static Scheme_Object *set_sfs(Scheme_Object *data, SFS_Info *info); +static Scheme_Object *define_syntaxes_sfs(Scheme_Object *expr, SFS_Info *info); +static Scheme_Object *define_for_syntaxes_sfs(Scheme_Object *expr, SFS_Info *info); +static Scheme_Object *case_lambda_sfs(Scheme_Object *expr, SFS_Info *info); +static Scheme_Object *begin0_sfs(Scheme_Object *data, SFS_Info *info); +static Scheme_Object *apply_values_sfs(Scheme_Object *data, SFS_Info *info); +static Scheme_Object *splice_sfs(Scheme_Object *data, SFS_Info *info); +static Scheme_Object *bangboxenv_sfs(Scheme_Object *data, SFS_Info *info); + static void define_values_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts); + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos); static void ref_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts); + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos); static void set_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts); + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos); static void define_syntaxes_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts); + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos); static void define_for_syntaxes_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts); + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos); static void case_lambda_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts); + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos); static void begin0_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts); + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos); static void apply_values_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts); + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos); static void splice_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts); + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos); static void bangboxenv_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts); + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos); static Scheme_Object *define_values_jit(Scheme_Object *data); static Scheme_Object *ref_jit(Scheme_Object *data); @@ -260,54 +282,54 @@ scheme_init_syntax (Scheme_Env *env) scheme_register_syntax(DEFINE_VALUES_EXPD, define_values_optimize, - define_values_resolve, define_values_validate, + define_values_resolve, define_values_sfs, define_values_validate, define_values_execute, define_values_jit, NULL, NULL, -2); scheme_register_syntax(SET_EXPD, set_optimize, - set_resolve, set_validate, + set_resolve, set_sfs, set_validate, set_execute, set_jit, set_clone, set_shift, 2); scheme_register_syntax(REF_EXPD, ref_optimize, - ref_resolve, ref_validate, + ref_resolve, ref_sfs, ref_validate, ref_execute, ref_jit, NULL, ref_shift, 0); scheme_register_syntax(DEFINE_SYNTAX_EXPD, define_syntaxes_optimize, - define_syntaxes_resolve, define_syntaxes_validate, + define_syntaxes_resolve, define_syntaxes_sfs, define_syntaxes_validate, define_syntaxes_execute, define_syntaxes_jit, NULL, NULL, -2); scheme_register_syntax(DEFINE_FOR_SYNTAX_EXPD, define_for_syntaxes_optimize, - define_for_syntaxes_resolve, define_for_syntaxes_validate, + define_for_syntaxes_resolve, define_for_syntaxes_sfs, define_for_syntaxes_validate, define_for_syntaxes_execute, define_for_syntaxes_jit, NULL, NULL, -2); scheme_register_syntax(CASE_LAMBDA_EXPD, case_lambda_optimize, - case_lambda_resolve, case_lambda_validate, + case_lambda_resolve, case_lambda_sfs, case_lambda_validate, case_lambda_execute, case_lambda_jit, NULL, case_lambda_shift, -1); scheme_register_syntax(BEGIN0_EXPD, begin0_optimize, - begin0_resolve, begin0_validate, + begin0_resolve, begin0_sfs, begin0_validate, begin0_execute, begin0_jit, begin0_clone, begin0_shift, -1); scheme_register_syntax(APPVALS_EXPD, apply_values_optimize, - apply_values_resolve, apply_values_validate, + apply_values_resolve, apply_values_sfs, apply_values_validate, apply_values_execute, apply_values_jit, apply_values_clone, apply_values_shift, 1); scheme_register_syntax(SPLICE_EXPD, splice_optimize, - splice_resolve, splice_validate, + splice_resolve, splice_sfs, splice_validate, splice_execute, splice_jit, splice_clone, splice_shift, 0); scheme_register_syntax(BOXENV_EXPD, - NULL, NULL, bangboxenv_validate, + NULL, NULL, bangboxenv_sfs, bangboxenv_validate, bangboxenv_execute, bangboxenv_jit, NULL, NULL, 1); @@ -846,7 +868,8 @@ static Scheme_Object *define_values_jit(Scheme_Object *data) static void define_values_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts) + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos) { int i, size; Scheme_Object *val, *only_var; @@ -954,7 +977,7 @@ static void define_values_validate(Scheme_Object *data, Mz_CPort *port, scheme_validate_expr(port, val, stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - NULL, !!only_var); + NULL, !!only_var, 0, vc, 0); } static Scheme_Object * @@ -1004,6 +1027,16 @@ define_values_resolve(Scheme_Object *data, Resolve_Info *rslv) return scheme_make_syntax_resolved(DEFINE_VALUES_EXPD, vec); } +static Scheme_Object * +define_values_sfs(Scheme_Object *data, SFS_Info *info) +{ + Scheme_Object *e; + scheme_sfs_start_sequence(info, 1, 0); + e = scheme_sfs_expr(SCHEME_VEC_ELS(data)[0], info, -1); + SCHEME_VEC_ELS(data)[0] = e; + return data; +} + void scheme_resolve_lift_definition(Resolve_Info *info, Scheme_Object *var, Scheme_Object *rhs) { Scheme_Object *decl, *vec, *pr; @@ -1474,7 +1507,8 @@ static Scheme_Object *set_jit(Scheme_Object *data) static void set_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts) + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos) { Scheme_Object *val, *tl; @@ -1488,7 +1522,7 @@ static void set_validate(Scheme_Object *data, Mz_CPort *port, scheme_validate_expr(port, val, stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - NULL, 0); + NULL, 0, 0, vc, 0); scheme_validate_toplevel(tl, port, stack, tls, depth, delta, num_toplevels, num_stxes, num_lifts, 0); @@ -1520,7 +1554,7 @@ set_optimize(Scheme_Object *data, Optimize_Info *info) /* Offset: */ delta = scheme_optimize_info_get_shift(info, pos); if (delta) - var = scheme_make_local(scheme_local_type, pos + delta); + var = scheme_make_local(scheme_local_type, pos + delta, 0); } else { scheme_optimize_info_used_top(info); } @@ -1602,6 +1636,26 @@ set_resolve(Scheme_Object *data, Resolve_Info *rslv) return scheme_make_syntax_resolved(SET_EXPD, cons(set_undef, cons(var, val))); } +static Scheme_Object * +set_sfs(Scheme_Object *orig_data, SFS_Info *info) +{ + Scheme_Object *data, *var, *val; + + data = SCHEME_CDR(orig_data); + var = SCHEME_CAR(data); + val = SCHEME_CDR(data); + + scheme_sfs_start_sequence(info, 2, 0); + + val = scheme_sfs_expr(val, info, -1); + var = scheme_sfs_expr(var, info, -1); + + SCHEME_CAR(data) = var; + SCHEME_CDR(data) = val; + + return orig_data; +} + static Scheme_Object * set_syntax (Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_Info *rec, int drec) { @@ -1813,7 +1867,8 @@ static Scheme_Object *ref_jit(Scheme_Object *data) static void ref_validate(Scheme_Object *tl, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts) + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos) { scheme_validate_toplevel(tl, port, stack, tls, depth, delta, num_toplevels, num_stxes, num_lifts, @@ -1841,6 +1896,18 @@ ref_resolve(Scheme_Object *tl, Resolve_Info *rslv) return scheme_make_syntax_resolved(REF_EXPD, scheme_resolve_expr(tl, rslv)); } +static Scheme_Object * +ref_sfs(Scheme_Object *tl, SFS_Info *info) +{ + Scheme_Object *naya; + scheme_sfs_start_sequence(info, 1, 0); + naya = scheme_sfs_expr(tl, info, -1); + if (SAME_OBJ(naya, tl)) + return tl; + else + return scheme_make_syntax_resolved(REF_EXPD, naya); +} + static Scheme_Object * ref_syntax (Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_Info *rec, int drec) { @@ -2019,6 +2086,22 @@ apply_values_resolve(Scheme_Object *data, Resolve_Info *rslv) return scheme_make_syntax_resolved(APPVALS_EXPD, cons(f, e)); } +static Scheme_Object * +apply_values_sfs(Scheme_Object *data, SFS_Info *info) +{ + Scheme_Object *f, *e; + + f = SCHEME_CAR(data); + e = SCHEME_CDR(data); + + scheme_sfs_start_sequence(info, 2, 0); + + f = scheme_sfs_expr(f, info, -1); + e = scheme_sfs_expr(e, info, -1); + + return data; +} + static Scheme_Object * apply_values_shift(Scheme_Object *data, int delta, int after_depth) { @@ -2052,7 +2135,8 @@ apply_values_clone(int dup_ok, Scheme_Object *data, Optimize_Info *info, int del static void apply_values_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts) + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos) { Scheme_Object *f, *e; @@ -2062,11 +2146,11 @@ static void apply_values_validate(Scheme_Object *data, Mz_CPort *port, scheme_validate_expr(port, f, stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - NULL, 0); + NULL, 0, 0, vc, 0); scheme_validate_expr(port, e, stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - NULL, 0); + NULL, 0, 0, vc, 0); } /**********************************************************************/ @@ -2215,15 +2299,21 @@ static Scheme_Object *case_lambda_jit(Scheme_Object *expr) static void case_lambda_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts) + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos) { Scheme_Case_Lambda *seq = (Scheme_Case_Lambda *)data; + Scheme_Object *e; int i; for (i = 0; i < seq->count; i++) { - scheme_validate_expr(port, seq->array[i], stack, tls, depth, letlimit, delta, + e = seq->array[i]; + if (!SAME_TYPE(SCHEME_TYPE(e), scheme_unclosed_procedure_type) + && !SAME_TYPE(SCHEME_TYPE(e), scheme_closure_type)) + scheme_ill_formed_code(port); + scheme_validate_expr(port, e, stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - NULL, 0); + NULL, 0, 0, vc, 0); } } @@ -2250,6 +2340,48 @@ case_lambda_resolve(Scheme_Object *expr, Resolve_Info *rslv) return scheme_make_syntax_resolved(CASE_LAMBDA_EXPD, expr); } +static Scheme_Object * +case_lambda_sfs(Scheme_Object *expr, SFS_Info *info) +{ + Scheme_Case_Lambda *seq = (Scheme_Case_Lambda *)expr; + Scheme_Object *le, *clears = scheme_null; + int i; + + scheme_sfs_start_sequence(info, seq->count, 0); + + for (i = 0; i < seq->count; i++) { + le = seq->array[i]; + le = scheme_sfs_expr(le, info, -1); + if (SAME_TYPE(SCHEME_TYPE(le), scheme_syntax_type) + && (SCHEME_PINT_VAL(le) == BEGIN0_EXPD)) { + /* Some clearing actions were added to the closure. + Lift them out. */ + int j; + Scheme_Sequence *cseq = (Scheme_Sequence *)SCHEME_IPTR_VAL(le); + if (!cseq->count) + scheme_signal_error("internal error: empty sequence"); + for (j = 1; j < cseq->count; j++) { + int pos; + pos = SCHEME_LOCAL_POS(cseq->array[j]); + clears = scheme_make_pair(scheme_make_integer(pos), clears); + } + le = cseq->array[0]; + } + if (!SAME_TYPE(SCHEME_TYPE(le), scheme_unclosed_procedure_type) + && !SAME_TYPE(SCHEME_TYPE(le), scheme_closure_type)) { + scheme_signal_error("internal error: not a lambda for case-lambda: %d", + SCHEME_TYPE(le)); + } + seq->array[i] = le; + } + + if (!SCHEME_NULLP(clears)) { + expr = scheme_make_syntax_resolved(CASE_LAMBDA_EXPD, expr); + return scheme_sfs_add_clears(expr, clears, 0); + } else + return expr; +} + static Scheme_Object * case_lambda_optimize(Scheme_Object *expr, Optimize_Info *info) { @@ -2285,7 +2417,7 @@ case_lambda_shift(Scheme_Object *data, int delta, int after_depth) return data; } -Scheme_Object *scheme_unclose_case_lambda(Scheme_Object *expr, int jit) +Scheme_Object *scheme_unclose_case_lambda(Scheme_Object *expr, int mode) { Scheme_Case_Lambda *cl = (Scheme_Case_Lambda *)expr; Scheme_Closure *c; @@ -2314,9 +2446,13 @@ Scheme_Object *scheme_unclose_case_lambda(Scheme_Object *expr, int jit) cl2->array[i] = (Scheme_Object *)c->code; } - if (jit) + if (mode == 2) { + /* sfs */ + return scheme_make_syntax_resolved(CASE_LAMBDA_EXPD, expr); + } else if (mode == 1) { + /* JIT */ return case_lambda_jit((Scheme_Object *)cl2); - else + } else return (Scheme_Object *)cl2; } @@ -2535,6 +2671,14 @@ Scheme_Object *bangboxenv_execute(Scheme_Object *data) return _scheme_tail_eval(data); } +static Scheme_Object *bangboxenv_sfs(Scheme_Object *data, SFS_Info *info) +{ + Scheme_Object *e; + e = scheme_sfs_expr(SCHEME_CDR(data), info, -1); + SCHEME_CDR(data) = e; + return data; +} + static Scheme_Object *bangboxenv_jit(Scheme_Object *data) { Scheme_Object *orig, *naya; @@ -2550,7 +2694,8 @@ static Scheme_Object *bangboxenv_jit(Scheme_Object *data) static void bangboxenv_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts) + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos) { if (!SCHEME_PAIRP(data)) scheme_ill_formed_code(port); @@ -2559,7 +2704,7 @@ static void bangboxenv_validate(Scheme_Object *data, Mz_CPort *port, scheme_validate_expr(port, SCHEME_CDR(data), stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - NULL, 0); + NULL, 0, 0, vc, tailpos); } /**********************************************************************/ @@ -4365,16 +4510,21 @@ static Scheme_Object *begin0_jit(Scheme_Object *data) static void begin0_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts) + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos) { Scheme_Sequence *seq = (Scheme_Sequence *)data; int i; + if (!SAME_TYPE(SCHEME_TYPE(seq), scheme_begin0_sequence_type) + && !SAME_TYPE(SCHEME_TYPE(seq), scheme_sequence_type)) + scheme_ill_formed_code(port); + for (i = 0; i < seq->count; i++) { scheme_validate_expr(port, seq->array[i], stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - NULL, 0); + NULL, 0, i > 0, vc, 0); } } @@ -4436,6 +4586,24 @@ begin0_resolve(Scheme_Object *obj, Resolve_Info *info) return scheme_make_syntax_resolved(BEGIN0_EXPD, obj); } +static Scheme_Object * +begin0_sfs(Scheme_Object *obj, SFS_Info *info) +{ + int i, cnt; + + cnt = ((Scheme_Sequence *)obj)->count; + + scheme_sfs_start_sequence(info, cnt, 0); + + for (i = 0; i < cnt; i++) { + Scheme_Object *le; + le = scheme_sfs_expr(((Scheme_Sequence *)obj)->array[i], info, -1); + ((Scheme_Sequence *)obj)->array[i] = le; + } + + return obj; +} + static Scheme_Object * do_begin_syntax(char *name, Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_Info *rec, int drec, @@ -4659,6 +4827,17 @@ splice_resolve(Scheme_Object *data, Resolve_Info *rslv) scheme_resolve_expr(data, rslv)); } +static Scheme_Object * +splice_sfs(Scheme_Object *data, SFS_Info *info) +{ + Scheme_Object *naya; + naya = scheme_sfs_expr(data, info, -1); + if (SAME_OBJ(naya, data)) + return data; + else + return scheme_make_syntax_resolved(SPLICE_EXPD, data); +} + static Scheme_Object * splice_shift(Scheme_Object *data, int delta, int after_depth) { @@ -4677,12 +4856,13 @@ splice_clone(int dup_ok, Scheme_Object *data, Optimize_Info *info, int delta, in static void splice_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts) + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos) { scheme_validate_expr(port, data, stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, - NULL, 0); + NULL, 0, 0, vc, 0); } /**********************************************************************/ @@ -4965,7 +5145,8 @@ static void do_define_syntaxes_validate(Scheme_Object *data, Mz_CPort *port, static void define_syntaxes_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts) + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos) { do_define_syntaxes_validate(data, port, stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, 0); @@ -4974,7 +5155,8 @@ static void define_syntaxes_validate(Scheme_Object *data, Mz_CPort *port, static void define_for_syntaxes_validate(Scheme_Object *data, Mz_CPort *port, char *stack, Validate_TLS tls, int depth, int letlimit, int delta, - int num_toplevels, int num_stxes, int num_lifts) + int num_toplevels, int num_stxes, int num_lifts, + struct Validate_Clearing *vc, int tailpos) { do_define_syntaxes_validate(data, port, stack, tls, depth, letlimit, delta, num_toplevels, num_stxes, num_lifts, 1); @@ -5071,6 +5253,31 @@ static Scheme_Object *define_for_syntaxes_resolve(Scheme_Object *data, Resolve_I return do_define_syntaxes_resolve(data, info, 1); } +static Scheme_Object *do_define_syntaxes_sfs(Scheme_Object *data, SFS_Info *info) +{ + Scheme_Object *e; + + if (!info->pass) { + int depth; + depth = SCHEME_INT_VAL(SCHEME_VEC_ELS(data)[2]); + info = scheme_new_sfs_info(depth); + e = scheme_sfs(SCHEME_VEC_ELS(data)[0], info, depth); + SCHEME_VEC_ELS(data)[0] = e; + } + + return data; +} + +static Scheme_Object *define_syntaxes_sfs(Scheme_Object *data, SFS_Info *info) +{ + return do_define_syntaxes_sfs(data, info); +} + +static Scheme_Object *define_for_syntaxes_sfs(Scheme_Object *data, SFS_Info *info) +{ + return do_define_syntaxes_sfs(data, info); +} + static Scheme_Object *stx_val(Scheme_Object *name, Scheme_Object *_env) { Scheme_Env *env = (Scheme_Env *)_env; diff --git a/src/mzscheme/src/vector.c b/src/mzscheme/src/vector.c index 75e89db5d9..1218f0ff71 100644 --- a/src/mzscheme/src/vector.c +++ b/src/mzscheme/src/vector.c @@ -34,6 +34,7 @@ static Scheme_Object *vector_length (int argc, Scheme_Object *argv[]); static Scheme_Object *vector_to_list (int argc, Scheme_Object *argv[]); static Scheme_Object *list_to_vector (int argc, Scheme_Object *argv[]); static Scheme_Object *vector_fill (int argc, Scheme_Object *argv[]); +static Scheme_Object *vector_copy_bang(int argc, Scheme_Object *argv[]); static Scheme_Object *vector_to_immutable (int argc, Scheme_Object *argv[]); static Scheme_Object *vector_to_values (int argc, Scheme_Object *argv[]); @@ -55,17 +56,17 @@ scheme_init_vector (Scheme_Env *env) scheme_add_global_constant("vector?", p, env); scheme_add_global_constant("make-vector", - scheme_make_noncm_prim(make_vector, + scheme_make_immed_prim(make_vector, "make-vector", 1, 2), env); scheme_add_global_constant("vector", - scheme_make_noncm_prim(vector, + scheme_make_immed_prim(vector, "vector", 0, -1), env); scheme_add_global_constant("vector-immutable", - scheme_make_noncm_prim(vector_immutable, + scheme_make_immed_prim(vector_immutable, "vector-immutable", 0, -1), env); @@ -75,35 +76,40 @@ scheme_init_vector (Scheme_Env *env) 1, 1, 1), env); - p = scheme_make_noncm_prim(scheme_checked_vector_ref, + p = scheme_make_immed_prim(scheme_checked_vector_ref, "vector-ref", 2, 2); SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; scheme_add_global_constant("vector-ref", p, env); - p = scheme_make_noncm_prim(scheme_checked_vector_set, + p = scheme_make_immed_prim(scheme_checked_vector_set, "vector-set!", 3, 3); SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_MIN_NARY_INLINED; scheme_add_global_constant("vector-set!", p, env); scheme_add_global_constant("vector->list", - scheme_make_noncm_prim(vector_to_list, + scheme_make_immed_prim(vector_to_list, "vector->list", 1, 1), env); scheme_add_global_constant("list->vector", - scheme_make_noncm_prim(list_to_vector, + scheme_make_immed_prim(list_to_vector, "list->vector", 1, 1), env); scheme_add_global_constant("vector-fill!", - scheme_make_noncm_prim(vector_fill, + scheme_make_immed_prim(vector_fill, "vector-fill!", 2, 2), env); + scheme_add_global_constant("vector-copy!", + scheme_make_immed_prim(vector_copy_bang, + "vector-copy!", + 3, 5), + env); scheme_add_global_constant("vector->immutable-vector", - scheme_make_noncm_prim(vector_to_immutable, + scheme_make_immed_prim(vector_to_immutable, "vector->immutable-vector", 1, 1), env); @@ -356,6 +362,42 @@ vector_fill (int argc, Scheme_Object *argv[]) return argv[0]; } +static Scheme_Object *vector_copy_bang(int argc, Scheme_Object *argv[]) +{ + Scheme_Object *s1, *s2; + long istart, ifinish; + long ostart, ofinish; + + s1 = argv[0]; + if (!SCHEME_MUTABLE_VECTORP(s1)) + scheme_wrong_type("vector-copy!", "mutable vector", 0, argc, argv); + + scheme_do_get_substring_indices("vector-copy!", s1, + argc, argv, 1, 5, + &ostart, &ofinish, SCHEME_VEC_SIZE(s1)); + + s2 = argv[2]; + if (!SCHEME_VECTORP(s2)) + scheme_wrong_type("vector-copy!", "vector", 2, argc, argv); + + scheme_do_get_substring_indices("vector-copy!", s2, + argc, argv, 3, 4, + &istart, &ifinish, SCHEME_VEC_SIZE(s2)); + + if ((ofinish - ostart) < (ifinish - istart)) { + scheme_arg_mismatch("vector-copy!", + "not enough room in target vector: ", + argv[2]); + return NULL; + } + + memmove(SCHEME_VEC_ELS(s1) + ostart, + SCHEME_VEC_ELS(s2) + istart, + (ifinish - istart) * sizeof(Scheme_Object*)); + + return scheme_void; +} + static Scheme_Object *vector_to_immutable (int argc, Scheme_Object *argv[]) { Scheme_Object *vec, *ovec;