352.5
svn: r4169
This commit is contained in:
parent
2c8ab78953
commit
86900d573a
|
@ -122,7 +122,9 @@ the Unix instructions below, but note the following:
|
|||
For cross compilation, set the compiler variables to a compiler
|
||||
for the target platform compiler, but also set CC_FOR_BUILD to a
|
||||
compiler for the host platform (for building binaries to execute
|
||||
during the build process).
|
||||
during the build process). If the target machine's stack grows up,
|
||||
you'll have to supply --enable-stackup; if the target machine is
|
||||
big-endian, you may have to supply --enable-bigendian.
|
||||
|
||||
If you re-run `configure' after running `make', then products of
|
||||
the `make' may be incorrect due to changes in the compiler command
|
||||
|
|
30
src/configure
vendored
30
src/configure
vendored
|
@ -875,6 +875,8 @@ Optional Features:
|
|||
--enable-float include support for single-precision floats
|
||||
--enable-floatinstead compile to use single-precision by default
|
||||
--enable-pthread link MrEd with pthreads (sometimes needed for GL)
|
||||
--enable-stackup assume "up" if stack direction cannot be determined
|
||||
--enable-bigendian assume "big" if endianness cannot be determined
|
||||
--enable-oskit compile OSKit-based MzScheme kernel
|
||||
--enable-smalloskit compile small OSKit-based MzScheme kernel
|
||||
--enable-wbuild compile and use wbuild for .w sources
|
||||
|
@ -1466,6 +1468,16 @@ fi;
|
|||
if test "${enable_pthread+set}" = set; then
|
||||
enableval="$enable_pthread"
|
||||
|
||||
fi;
|
||||
# Check whether --enable-stackup or --disable-stackup was given.
|
||||
if test "${enable_stackup+set}" = set; then
|
||||
enableval="$enable_stackup"
|
||||
|
||||
fi;
|
||||
# Check whether --enable-bigendian or --disable-bigendian was given.
|
||||
if test "${enable_bigendian+set}" = set; then
|
||||
enableval="$enable_bigendian"
|
||||
|
||||
fi;
|
||||
|
||||
# Check whether --enable-oskit or --disable-oskit was given.
|
||||
|
@ -8323,7 +8335,7 @@ int grows_down_p(int n, void *cmp) {
|
|||
return grows_down_p(n - 1, cmp);
|
||||
}
|
||||
int main() {
|
||||
return grows_down_p();
|
||||
return grows_down_p(0, 0);
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest$ac_exeext
|
||||
|
@ -8352,8 +8364,11 @@ echo "$as_me:$LINENO: result: $stack_direction" >&5
|
|||
echo "${ECHO_T}$stack_direction" >&6
|
||||
|
||||
if test "${stack_direction}" = "unknown" ; then
|
||||
echo configure: cannot determine stack direction
|
||||
exit 1
|
||||
if test "${enable_stackup}" = "yes" ; then
|
||||
stack_direction=up
|
||||
else
|
||||
echo configure: warning: cannot determine stack direction, assuming down
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "${stack_direction}" = "up" ; then
|
||||
|
@ -8590,12 +8605,15 @@ case $ac_cv_c_bigendian in
|
|||
no)
|
||||
endianness=little ;;
|
||||
*)
|
||||
endiannes=unknown ;;
|
||||
endianness=unknown ;;
|
||||
esac
|
||||
|
||||
if test "${endianness}" = "unknown" ; then
|
||||
echo configure: cannot determine endianness
|
||||
exit 1
|
||||
if test "${enable_bigendian}" = "yes" ; then
|
||||
endianness=big
|
||||
else
|
||||
echo configure: warning: cannot determine endianness, assuming little
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "${endianness}" = "big" ; then
|
||||
|
|
|
@ -217,6 +217,10 @@ typedef void *(*CAPOFunc)(void*);
|
|||
|
||||
|
||||
|
||||
// No OnScroll, because it's handled more primitively to better support
|
||||
// interactive scrolling on Mac OS X and Windows
|
||||
// @ v "on-scroll" : void OnScroll(wxScrollEvent!); : JMPDECL/SETJMP/RESETJMP
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -72,6 +72,10 @@ typedef void *(*CAPOFunc)(void*);
|
|||
|
||||
@ v "on-scroll-on-change" : void OnScrollOnChange();
|
||||
|
||||
// No OnScroll, because it's handled more primitively to better support
|
||||
// interactive scrolling on Mac OS X and Windows
|
||||
// @ v "on-scroll" : void OnScroll(wxScrollEvent!); : JMPDECL/SETJMP/RESETJMP
|
||||
|
||||
@ "is-focus-on?" : bool IsFocusOn();
|
||||
|
||||
@ "force-display-focus" : void ForceDisplayFocus(bool);
|
||||
|
|
|
@ -52,6 +52,8 @@ AC_ARG_ENABLE(float, [ --enable-float include support for single-pre
|
|||
AC_ARG_ENABLE(floatinstead, [ --enable-floatinstead compile to use single-precision by default])
|
||||
|
||||
AC_ARG_ENABLE(pthread, [ --enable-pthread link MrEd with pthreads (sometimes needed for GL)])
|
||||
AC_ARG_ENABLE(stackup, [ --enable-stackup assume "up" if stack direction cannot be determined])
|
||||
AC_ARG_ENABLE(bigendian, [ --enable-bigendian assume "big" if endianness cannot be determined])
|
||||
|
||||
AC_ARG_ENABLE(oskit, [ --enable-oskit compile OSKit-based MzScheme kernel])
|
||||
AC_ARG_ENABLE(smalloskit, [ --enable-smalloskit compile small OSKit-based MzScheme kernel])
|
||||
|
@ -766,13 +768,16 @@ AC_TRY_RUN(
|
|||
return grows_down_p(n - 1, cmp);
|
||||
}
|
||||
int main() {
|
||||
return grows_down_p();
|
||||
return grows_down_p(0, 0);
|
||||
}, stack_direction=up, stack_direction=down, stack_direction=unknown)
|
||||
AC_MSG_RESULT($stack_direction)
|
||||
|
||||
if test "${stack_direction}" = "unknown" ; then
|
||||
echo configure: cannot determine stack direction
|
||||
exit 1
|
||||
if test "${enable_stackup}" = "yes" ; then
|
||||
stack_direction=up
|
||||
else
|
||||
echo configure: warning: cannot determine stack direction, assuming down
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "${stack_direction}" = "up" ; then
|
||||
|
@ -782,10 +787,13 @@ if test "${stack_direction}" = "down" ; then
|
|||
AC_DEFINE(STACK_DIRECTION,-1,[Stack direction down])
|
||||
fi
|
||||
|
||||
AC_C_BIGENDIAN(endianness=big, endianness=little, endiannes=unknown)
|
||||
AC_C_BIGENDIAN(endianness=big, endianness=little, endianness=unknown)
|
||||
if test "${endianness}" = "unknown" ; then
|
||||
echo configure: cannot determine endianness
|
||||
exit 1
|
||||
if test "${enable_bigendian}" = "yes" ; then
|
||||
endianness=big
|
||||
else
|
||||
echo configure: warning: cannot determine endianness, assuming little
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "${endianness}" = "big" ; then
|
||||
|
|
|
@ -315,14 +315,15 @@ static struct mpage *page_map[1 << USEFUL_ADDR_BITS];
|
|||
entire nursery on every GC. The latter is useful because it simplifies
|
||||
the allocation process (which is also a speed hack, come to think of it)
|
||||
|
||||
gen0_pages is the list of very large nursery pages. gen0_alloc_page is
|
||||
gen0_pages is the list of very large nursery pages. GC_gen0_alloc_page is
|
||||
the member of this list we are currently allocating on. The size count
|
||||
helps us trigger collection quickly when we're running out of space; see
|
||||
the test in allocate_big.
|
||||
*/
|
||||
static struct mpage *gen0_pages = NULL;
|
||||
static struct mpage *gen0_alloc_page = NULL;
|
||||
static struct mpage *GC_gen0_alloc_page = NULL;
|
||||
static struct mpage *gen0_big_pages = NULL;
|
||||
static unsigned long GC_gen0_alloc_page_size = 0;
|
||||
static unsigned long gen0_current_size = 0;
|
||||
static unsigned long gen0_max_size = 0;
|
||||
|
||||
|
@ -439,20 +440,24 @@ inline static void *allocate(size_t sizeb, int type)
|
|||
|
||||
sizeb = gcWORDS_TO_BYTES(sizew);
|
||||
alloc_retry:
|
||||
newsize = gen0_alloc_page->size + sizeb;
|
||||
newsize = GC_gen0_alloc_page_size + sizeb;
|
||||
|
||||
if(newsize > GEN0_PAGE_SIZE) {
|
||||
if(gen0_alloc_page->next)
|
||||
gen0_alloc_page = gen0_alloc_page->next;
|
||||
else if (avoid_collection) {
|
||||
gen0_current_size += (GC_gen0_alloc_page_size - HEADER_SIZEB);
|
||||
GC_gen0_alloc_page->size = GC_gen0_alloc_page_size;
|
||||
if(GC_gen0_alloc_page->next) {
|
||||
GC_gen0_alloc_page = GC_gen0_alloc_page->next;
|
||||
GC_gen0_alloc_page_size = GC_gen0_alloc_page->size;
|
||||
} else if (avoid_collection) {
|
||||
struct mpage *work;
|
||||
|
||||
work = malloc_pages(GEN0_PAGE_SIZE, APAGE_SIZE);
|
||||
work->size = GEN0_PAGE_SIZE;
|
||||
work->big_page = 1;
|
||||
gen0_alloc_page->prev = work;
|
||||
work->next = gen0_alloc_page;
|
||||
gen0_alloc_page = work;
|
||||
GC_gen0_alloc_page->prev = work;
|
||||
work->next = GC_gen0_alloc_page;
|
||||
GC_gen0_alloc_page = work;
|
||||
GC_gen0_alloc_page_size = GC_gen0_alloc_page->size;
|
||||
pagemap_add(work);
|
||||
work->size = HEADER_SIZEB;
|
||||
work->big_page = 0;
|
||||
|
@ -460,7 +465,7 @@ inline static void *allocate(size_t sizeb, int type)
|
|||
garbage_collect(0);
|
||||
goto alloc_retry;
|
||||
} else {
|
||||
void *retval = PTR(NUM(gen0_alloc_page) + gen0_alloc_page->size);
|
||||
void *retval = PTR(NUM(GC_gen0_alloc_page) + GC_gen0_alloc_page_size);
|
||||
|
||||
if (type == PAGE_ATOMIC)
|
||||
*((void **)retval) = NULL; /* init objhead */
|
||||
|
@ -470,8 +475,7 @@ inline static void *allocate(size_t sizeb, int type)
|
|||
info = (struct objhead *)retval;
|
||||
info->type = type;
|
||||
info->size = sizew;
|
||||
gen0_alloc_page->size = newsize;
|
||||
gen0_current_size += sizeb;
|
||||
GC_gen0_alloc_page_size = newsize;
|
||||
|
||||
return PTR(NUM(retval) + WORD_SIZE);
|
||||
}
|
||||
|
@ -495,20 +499,19 @@ void *GC_malloc_one_small_tagged(size_t sizeb)
|
|||
|
||||
sizeb += WORD_SIZE;
|
||||
sizeb = ALIGN_BYTES_SIZE(sizeb);
|
||||
newsize = gen0_alloc_page->size + sizeb;
|
||||
newsize = GC_gen0_alloc_page_size + sizeb;
|
||||
|
||||
if(newsize > GEN0_PAGE_SIZE) {
|
||||
return GC_malloc_one_tagged(sizeb - WORD_SIZE);
|
||||
} else {
|
||||
void *retval = PTR(NUM(gen0_alloc_page) + gen0_alloc_page->size);
|
||||
void *retval = PTR(NUM(GC_gen0_alloc_page) + GC_gen0_alloc_page_size);
|
||||
struct objhead *info = (struct objhead *)retval;
|
||||
|
||||
bzero(retval, sizeb);
|
||||
|
||||
/* info->type = type; */ /* We know that the type field is already 0 */
|
||||
info->size = (sizeb >> gcLOG_WORD_SIZE);
|
||||
gen0_alloc_page->size = newsize;
|
||||
gen0_current_size += sizeb;
|
||||
GC_gen0_alloc_page_size = newsize;
|
||||
|
||||
return PTR(NUM(retval) + WORD_SIZE);
|
||||
}
|
||||
|
@ -520,19 +523,18 @@ void *GC_malloc_one_small_dirty_tagged(size_t sizeb)
|
|||
|
||||
sizeb += WORD_SIZE;
|
||||
sizeb = ALIGN_BYTES_SIZE(sizeb);
|
||||
newsize = gen0_alloc_page->size + sizeb;
|
||||
newsize = GC_gen0_alloc_page_size + sizeb;
|
||||
|
||||
if(newsize > GEN0_PAGE_SIZE) {
|
||||
return GC_malloc_one_tagged(sizeb - WORD_SIZE);
|
||||
} else {
|
||||
void *retval = PTR(NUM(gen0_alloc_page) + gen0_alloc_page->size);
|
||||
void *retval = PTR(NUM(GC_gen0_alloc_page) + GC_gen0_alloc_page_size);
|
||||
struct objhead *info = (struct objhead *)retval;
|
||||
|
||||
*(void **)info = NULL; /* client promises the initialize the rest */
|
||||
|
||||
info->size = (sizeb >> gcLOG_WORD_SIZE);
|
||||
gen0_alloc_page->size = newsize;
|
||||
gen0_current_size += sizeb;
|
||||
GC_gen0_alloc_page_size = newsize;
|
||||
|
||||
return PTR(NUM(retval) + WORD_SIZE);
|
||||
}
|
||||
|
@ -545,7 +547,7 @@ void *GC_malloc_pair(void *car, void *cdr)
|
|||
void *retval;
|
||||
|
||||
sizeb = ALIGN_BYTES_SIZE(gcWORDS_TO_BYTES(gcBYTES_TO_WORDS(sizeof(Scheme_Simple_Object))) + WORD_SIZE);
|
||||
newsize = gen0_alloc_page->size + sizeb;
|
||||
newsize = GC_gen0_alloc_page_size + sizeb;
|
||||
|
||||
if(newsize > GEN0_PAGE_SIZE) {
|
||||
park[0] = car;
|
||||
|
@ -558,7 +560,7 @@ void *GC_malloc_pair(void *car, void *cdr)
|
|||
} else {
|
||||
struct objhead *info;
|
||||
|
||||
retval = PTR(NUM(gen0_alloc_page) + gen0_alloc_page->size);
|
||||
retval = PTR(NUM(GC_gen0_alloc_page) + GC_gen0_alloc_page_size);
|
||||
info = (struct objhead *)retval;
|
||||
|
||||
((void **)retval)[0] = NULL; /* objhead */
|
||||
|
@ -566,8 +568,7 @@ void *GC_malloc_pair(void *car, void *cdr)
|
|||
|
||||
/* info->type = type; */ /* We know that the type field is already 0 */
|
||||
info->size = (sizeb >> gcLOG_WORD_SIZE);
|
||||
gen0_alloc_page->size = newsize;
|
||||
gen0_current_size += sizeb;
|
||||
GC_gen0_alloc_page_size = newsize;
|
||||
|
||||
retval = PTR(NUM(retval) + WORD_SIZE);
|
||||
}
|
||||
|
@ -640,7 +641,8 @@ inline static void resize_gen0(unsigned long new_size)
|
|||
}
|
||||
|
||||
/* we're going to allocate onto the first page now */
|
||||
gen0_alloc_page = gen0_pages;
|
||||
GC_gen0_alloc_page = gen0_pages;
|
||||
GC_gen0_alloc_page_size = GC_gen0_alloc_page->size;
|
||||
|
||||
/* set the two size variables */
|
||||
gen0_max_size = alloced_size;
|
||||
|
@ -1848,7 +1850,7 @@ long GC_get_memory_use(void *o)
|
|||
retval = custodian_usage(arg);
|
||||
}
|
||||
} else {
|
||||
retval = gen0_current_size + memory_in_use;
|
||||
retval = gen0_current_size + (GC_gen0_alloc_page_size - HEADER_SIZEB) + memory_in_use;
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
@ -2216,7 +2218,8 @@ void GC_dump_with_traces(int flags,
|
|||
GCPRINT(GCOUTF, "End MzScheme3m\n");
|
||||
|
||||
GCWARN((GCOUTF, "Generation 0: %li of %li bytes used\n",
|
||||
gen0_current_size, gen0_max_size));
|
||||
gen0_current_size + (GC_gen0_alloc_page_size - HEADER_SIZEB),
|
||||
gen0_max_size));
|
||||
|
||||
for(i = 0; i < PAGE_TYPES; i++) {
|
||||
unsigned long total_use = 0, count = 0;
|
||||
|
|
|
@ -984,7 +984,7 @@ typedef struct Scheme_Thread {
|
|||
struct {
|
||||
Scheme_Object *tail_rator;
|
||||
Scheme_Object **tail_rands;
|
||||
int tail_num_rands;
|
||||
long tail_num_rands;
|
||||
} apply;
|
||||
struct {
|
||||
Scheme_Object **array;
|
||||
|
|
|
@ -252,7 +252,7 @@ eval.@LTO@: $(srcdir)/schpriv.h $(srcdir)/schexn.h $(SCONFIG) $(srcdir)/../inclu
|
|||
file.@LTO@: $(srcdir)/schpriv.h $(srcdir)/schexn.h $(SCONFIG) $(srcdir)/../include/scheme.h \
|
||||
$(srcdir)/../src/stypes.h $(srcdir)/mzmark.c
|
||||
fun.@LTO@: $(srcdir)/schpriv.h $(srcdir)/schexn.h $(SCONFIG) $(srcdir)/../include/scheme.h \
|
||||
$(srcdir)/../src/stypes.h $(srcdir)/mzmark.c
|
||||
$(srcdir)/../src/stypes.h $(srcdir)/mzmark.c $(srcdir)/schmap.inc
|
||||
hash.@LTO@: $(srcdir)/schpriv.h $(srcdir)/schexn.h $(SCONFIG) $(srcdir)/../include/scheme.h \
|
||||
$(srcdir)/../src/stypes.h
|
||||
image.@LTO@: $(srcdir)/schpriv.h $(srcdir)/schexn.h $(SCONFIG) $(srcdir)/../include/scheme.h \
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -247,7 +247,7 @@ static void register_traversers(void);
|
|||
#endif
|
||||
|
||||
/* Lookahead types for evaluating application arguments. */
|
||||
/* 4 cases + else => magic number for some compilers doing a switch */
|
||||
/* 4 cases + else => magic number for some compilers doing a switch? */
|
||||
enum {
|
||||
SCHEME_EVAL_CONSTANT = 0,
|
||||
SCHEME_EVAL_GLOBAL,
|
||||
|
@ -1972,6 +1972,8 @@ static Scheme_Object *apply_inlined(Scheme_Object *p, Scheme_Closure_Data *data,
|
|||
info = scheme_optimize_info_add_frame(info, 0, 0, 0);
|
||||
info->inline_fuel >>= 1;
|
||||
p = scheme_optimize_expr(p, info);
|
||||
info->next->single_result = info->single_result;
|
||||
info->next->preserves_marks = info->preserves_marks;
|
||||
scheme_optimize_info_done(info);
|
||||
return p;
|
||||
}
|
||||
|
@ -2021,7 +2023,9 @@ static Scheme_Object *apply_inlined(Scheme_Object *p, Scheme_Closure_Data *data,
|
|||
#endif
|
||||
|
||||
Scheme_Object *optimize_for_inline(Optimize_Info *info, Scheme_Object *le, int argc,
|
||||
Scheme_App_Rec *app, Scheme_App2_Rec *app2, Scheme_App3_Rec *app3)
|
||||
Scheme_App_Rec *app, Scheme_App2_Rec *app2, Scheme_App3_Rec *app3,
|
||||
int *_flags)
|
||||
/* If not app, app2, or app3, just return a known procedure, if any */
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
|
@ -2046,11 +2050,17 @@ Scheme_Object *optimize_for_inline(Optimize_Info *info, Scheme_Object *le, int a
|
|||
if (le && SAME_TYPE(SCHEME_TYPE(le), scheme_compiled_unclosed_procedure_type)) {
|
||||
Scheme_Closure_Data *data = (Scheme_Closure_Data *)le;
|
||||
int sz;
|
||||
|
||||
if (!app && !app2 && !app3) {
|
||||
return le;
|
||||
}
|
||||
|
||||
*_flags = SCHEME_CLOSURE_DATA_FLAGS(data);
|
||||
|
||||
if (data->num_params == argc) {
|
||||
sz = scheme_closure_body_size(data, 1);
|
||||
if ((sz >= 0) && (sz <= (info->inline_fuel * (argc + 2)))) {
|
||||
le = scheme_optimize_clone(data->code, info, offset, argc);
|
||||
le = scheme_optimize_clone(0, data->code, info, offset, argc);
|
||||
if (le) {
|
||||
LOG_INLINE(fprintf(stderr, "Inline %s\n", data->name ? scheme_write_to_string(data->name, NULL) : "???"));
|
||||
return apply_inlined(le, data, info, argc, app, app2, app3);
|
||||
|
@ -2064,6 +2074,11 @@ 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)
|
||||
*_flags = (CLOS_PRESERVES_MARKS | CLOS_SINGLE_RESULT);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2121,7 +2136,7 @@ static Scheme_Object *optimize_application(Scheme_Object *o, Optimize_Info *info
|
|||
{
|
||||
Scheme_Object *le;
|
||||
Scheme_App_Rec *app;
|
||||
int i, n, all_vals = 1;
|
||||
int i, n, all_vals = 1, rator_flags = 0;
|
||||
|
||||
app = (Scheme_App_Rec *)o;
|
||||
|
||||
|
@ -2132,7 +2147,7 @@ static Scheme_Object *optimize_application(Scheme_Object *o, Optimize_Info *info
|
|||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (!i) {
|
||||
le = optimize_for_inline(info, app->args[i], n - 1, app, NULL, NULL);
|
||||
le = optimize_for_inline(info, app->args[i], n - 1, app, NULL, NULL, &rator_flags);
|
||||
if (le)
|
||||
return le;
|
||||
}
|
||||
|
@ -2152,6 +2167,13 @@ static Scheme_Object *optimize_application(Scheme_Object *o, Optimize_Info *info
|
|||
|
||||
info->size += 1;
|
||||
|
||||
info->preserves_marks = !!(rator_flags & CLOS_PRESERVES_MARKS);
|
||||
info->single_result = !!(rator_flags & CLOS_SINGLE_RESULT);
|
||||
if (rator_flags & CLOS_RESULT_TENTATIVE) {
|
||||
info->preserves_marks = -info->preserves_marks;
|
||||
info->single_result = -info->single_result;
|
||||
}
|
||||
|
||||
return (Scheme_Object *)app;
|
||||
}
|
||||
|
||||
|
@ -2159,13 +2181,14 @@ static Scheme_Object *optimize_application2(Scheme_Object *o, Optimize_Info *inf
|
|||
{
|
||||
Scheme_App2_Rec *app;
|
||||
Scheme_Object *le;
|
||||
int rator_flags = 0;
|
||||
|
||||
app = (Scheme_App2_Rec *)o;
|
||||
|
||||
le = check_app_let_rator(o, app->rator, info, 1);
|
||||
if (le) return le;
|
||||
|
||||
le = optimize_for_inline(info, app->rator, 1, NULL, app, NULL);
|
||||
le = optimize_for_inline(info, app->rator, 1, NULL, app, NULL, &rator_flags);
|
||||
if (le)
|
||||
return le;
|
||||
|
||||
|
@ -2182,6 +2205,13 @@ static Scheme_Object *optimize_application2(Scheme_Object *o, Optimize_Info *inf
|
|||
|
||||
info->size += 1;
|
||||
|
||||
info->preserves_marks = !!(rator_flags & CLOS_PRESERVES_MARKS);
|
||||
info->single_result = !!(rator_flags & CLOS_SINGLE_RESULT);
|
||||
if (rator_flags & CLOS_RESULT_TENTATIVE) {
|
||||
info->preserves_marks = -info->preserves_marks;
|
||||
info->single_result = -info->single_result;
|
||||
}
|
||||
|
||||
return (Scheme_Object *)app;
|
||||
}
|
||||
|
||||
|
@ -2190,13 +2220,14 @@ static Scheme_Object *optimize_application3(Scheme_Object *o, Optimize_Info *inf
|
|||
Scheme_App3_Rec *app;
|
||||
Scheme_Object *le;
|
||||
int all_vals = 1;
|
||||
int rator_flags = 0;
|
||||
|
||||
app = (Scheme_App3_Rec *)o;
|
||||
|
||||
le = check_app_let_rator(o, app->rator, info, 2);
|
||||
if (le) return le;
|
||||
|
||||
le = optimize_for_inline(info, app->rator, 2, NULL, NULL, app);
|
||||
le = optimize_for_inline(info, app->rator, 2, NULL, NULL, app, &rator_flags);
|
||||
if (le)
|
||||
return le;
|
||||
|
||||
|
@ -2229,18 +2260,117 @@ static Scheme_Object *optimize_application3(Scheme_Object *o, Optimize_Info *inf
|
|||
|
||||
info->size += 1;
|
||||
|
||||
/* Check for (call-with-values (lambda () M) N): */
|
||||
if (SAME_OBJ(app->rator, scheme_call_with_values_proc)) {
|
||||
if (SAME_TYPE(SCHEME_TYPE(app->rand1), scheme_compiled_unclosed_procedure_type)) {
|
||||
Scheme_Closure_Data *data = (Scheme_Closure_Data *)app->rand1;
|
||||
|
||||
if (!data->num_params) {
|
||||
/* Convert to apply-values form: */
|
||||
return scheme_optimize_apply_values(app->rand2, data->code, info,
|
||||
((SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_SINGLE_RESULT)
|
||||
? ((SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_RESULT_TENTATIVE)
|
||||
? -1
|
||||
: 1)
|
||||
: 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
info->preserves_marks = !!(rator_flags & CLOS_PRESERVES_MARKS);
|
||||
info->single_result = !!(rator_flags & CLOS_SINGLE_RESULT);
|
||||
if (rator_flags & CLOS_RESULT_TENTATIVE) {
|
||||
info->preserves_marks = -info->preserves_marks;
|
||||
info->single_result = -info->single_result;
|
||||
}
|
||||
|
||||
return (Scheme_Object *)app;
|
||||
}
|
||||
|
||||
Scheme_Object *scheme_optimize_apply_values(Scheme_Object *f, Scheme_Object *e,
|
||||
Optimize_Info *info,
|
||||
int e_single_result)
|
||||
/* f and e are already optimized */
|
||||
{
|
||||
Scheme_Object *f_is_proc = NULL;
|
||||
|
||||
info->preserves_marks = 0;
|
||||
info->single_result = 0;
|
||||
|
||||
{
|
||||
Scheme_Object *rev;
|
||||
if (SAME_TYPE(SCHEME_TYPE(f), scheme_local_type)) {
|
||||
rev = scheme_optimize_reverse(info, SCHEME_LOCAL_POS(f), 1);
|
||||
} else
|
||||
rev = f;
|
||||
|
||||
if (rev) {
|
||||
int rator2_flags;
|
||||
Scheme_Object *o_f;
|
||||
o_f = optimize_for_inline(info, rev, 1, NULL, NULL, NULL, &rator2_flags);
|
||||
if (o_f) {
|
||||
f_is_proc = rev;
|
||||
|
||||
if (SAME_TYPE(SCHEME_TYPE(o_f), scheme_compiled_unclosed_procedure_type)) {
|
||||
Scheme_Closure_Data *data2 = (Scheme_Closure_Data *)o_f;
|
||||
int flags = SCHEME_CLOSURE_DATA_FLAGS(data2);
|
||||
info->preserves_marks = !!(flags & CLOS_PRESERVES_MARKS);
|
||||
info->single_result = !!(flags & CLOS_SINGLE_RESULT);
|
||||
if (flags & CLOS_RESULT_TENTATIVE) {
|
||||
info->preserves_marks = -info->preserves_marks;
|
||||
info->single_result = -info->single_result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!f_is_proc && SCHEME_PROCP(f)) {
|
||||
f_is_proc = f;
|
||||
}
|
||||
}
|
||||
|
||||
if (f_is_proc && (e_single_result > 0)) {
|
||||
/* Just make it an application (N M): */
|
||||
Scheme_App2_Rec *app2;
|
||||
Scheme_Object *cloned;
|
||||
|
||||
app2 = MALLOC_ONE_TAGGED(Scheme_App2_Rec);
|
||||
app2->iso.so.type = scheme_application2_type;
|
||||
|
||||
/* We'd like to try to inline here. The problem is that
|
||||
e (the argument) has been optimized already,
|
||||
which means it's in the wrong coordinate system.
|
||||
If we can shift-clone it, then it will be back in the right
|
||||
coordinates. */
|
||||
|
||||
cloned = scheme_optimize_clone(1, e, info, 0, 0);
|
||||
if (cloned) {
|
||||
app2->rator = f_is_proc;
|
||||
app2->rand = cloned;
|
||||
return optimize_application2((Scheme_Object *)app2, info);
|
||||
} else {
|
||||
app2->rator = f;
|
||||
app2->rand = e;
|
||||
return (Scheme_Object *)app2;
|
||||
}
|
||||
}
|
||||
|
||||
return scheme_make_syntax_compiled(APPVALS_EXPD, cons(f, e));
|
||||
}
|
||||
|
||||
static Scheme_Object *optimize_sequence(Scheme_Object *o, Optimize_Info *info)
|
||||
{
|
||||
Scheme_Sequence *s = (Scheme_Sequence *)o;
|
||||
Scheme_Object *le;
|
||||
int i;
|
||||
int drop = 0;
|
||||
int drop = 0, preserves_marks = 0, single_result = 0;
|
||||
|
||||
for (i = s->count; i--; ) {
|
||||
le = scheme_optimize_expr(s->array[i], info);
|
||||
if (i == s->count - 1) {
|
||||
single_result = info->single_result;
|
||||
preserves_marks = info->preserves_marks;
|
||||
}
|
||||
|
||||
/* Inlining and constant propagation can expose
|
||||
omittable expressions. */
|
||||
|
@ -2253,6 +2383,9 @@ static Scheme_Object *optimize_sequence(Scheme_Object *o, Optimize_Info *info)
|
|||
}
|
||||
}
|
||||
|
||||
info->preserves_marks = preserves_marks;
|
||||
info->single_result = single_result;
|
||||
|
||||
if (drop + 1 == s->count) {
|
||||
return s->array[drop];
|
||||
} else if (drop) {
|
||||
|
@ -2283,8 +2416,11 @@ int scheme_compiled_duplicate_ok(Scheme_Object *fb)
|
|||
|| SAME_OBJ(fb, scheme_true)
|
||||
|| SCHEME_FALSEP(fb)
|
||||
|| SCHEME_SYMBOLP(fb)
|
||||
|| SCHEME_KEYWORDP(fb)
|
||||
|| SCHEME_EOFP(fb)
|
||||
|| SCHEME_INTP(fb)
|
||||
|| SCHEME_NULLP(fb)
|
||||
|| (SCHEME_CHARP(fb) && (SCHEME_CHAR_VAL(fb) < 256))
|
||||
|| SAME_TYPE(SCHEME_TYPE(fb), scheme_local_type)
|
||||
/* Values that are hashed by the printer to avoid
|
||||
duplication: */
|
||||
|
@ -2299,6 +2435,7 @@ static Scheme_Object *optimize_branch(Scheme_Object *o, Optimize_Info *info)
|
|||
{
|
||||
Scheme_Branch_Rec *b;
|
||||
Scheme_Object *t, *tb, *fb;
|
||||
int preserves_marks = 1, single_result = 1;
|
||||
|
||||
b = (Scheme_Branch_Rec *)o;
|
||||
|
||||
|
@ -2338,8 +2475,17 @@ static Scheme_Object *optimize_branch(Scheme_Object *o, Optimize_Info *info)
|
|||
|
||||
tb = scheme_optimize_expr(tb, info);
|
||||
|
||||
if (!info->preserves_marks) preserves_marks = 0;
|
||||
if (!info->single_result) single_result = 0;
|
||||
|
||||
fb = scheme_optimize_expr(fb, info);
|
||||
|
||||
if (!info->preserves_marks) preserves_marks = 0;
|
||||
if (!info->single_result) single_result = 0;
|
||||
|
||||
info->preserves_marks = preserves_marks;
|
||||
info->single_result = single_result;
|
||||
|
||||
/* Try optimize: (if x x #f) => x */
|
||||
if (SAME_TYPE(SCHEME_TYPE(t), scheme_local_type)
|
||||
&& SAME_TYPE(SCHEME_TYPE(tb), scheme_local_type)
|
||||
|
@ -2386,6 +2532,9 @@ static Scheme_Object *optimize_wcm(Scheme_Object *o, Optimize_Info *info)
|
|||
|
||||
b = scheme_optimize_expr(wcm->body, info);
|
||||
|
||||
/* info->single_result is already set */
|
||||
info->preserves_marks = 0;
|
||||
|
||||
wcm->key = k;
|
||||
wcm->val = v;
|
||||
wcm->body = b;
|
||||
|
@ -2423,6 +2572,9 @@ Scheme_Object *scheme_optimize_expr(Scheme_Object *expr, Optimize_Info *info)
|
|||
}
|
||||
#endif
|
||||
|
||||
info->preserves_marks = 1;
|
||||
info->single_result = 1;
|
||||
|
||||
switch (type) {
|
||||
case scheme_local_type:
|
||||
{
|
||||
|
@ -2519,31 +2671,11 @@ Scheme_Object *scheme_optimize_expr(Scheme_Object *expr, Optimize_Info *info)
|
|||
}
|
||||
}
|
||||
|
||||
Scheme_Object *scheme_optimize_list(Scheme_Object *expr, Optimize_Info *info)
|
||||
{
|
||||
Scheme_Object *first = scheme_null, *last = NULL;
|
||||
|
||||
while (SCHEME_PAIRP(expr)) {
|
||||
Scheme_Object *pr;
|
||||
|
||||
pr = scheme_make_pair(scheme_optimize_expr(SCHEME_CAR(expr), info),
|
||||
scheme_null);
|
||||
|
||||
if (last)
|
||||
SCHEME_CDR(last) = pr;
|
||||
else
|
||||
first = pr;
|
||||
last = pr;
|
||||
|
||||
expr = SCHEME_CDR(expr);
|
||||
}
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
Scheme_Object *scheme_optimize_clone(Scheme_Object *expr, Optimize_Info *info, int delta, int closure_depth)
|
||||
Scheme_Object *scheme_optimize_clone(int dup_ok, Scheme_Object *expr, Optimize_Info *info, int delta, int closure_depth)
|
||||
/* Past closure_depth, need to reverse optimize to unoptimzed with respect to info;
|
||||
delta is the amount to skip in info to get to the frame that bound the code */
|
||||
delta is the amount to skip in info to get to the frame that bound the code.
|
||||
If dup_ok is 1, then the old copy will be dropped, so it's ok to "duplicate"
|
||||
any constant. */
|
||||
{
|
||||
int t;
|
||||
|
||||
|
@ -2566,7 +2698,7 @@ Scheme_Object *scheme_optimize_clone(Scheme_Object *expr, Optimize_Info *info, i
|
|||
|
||||
f = scheme_syntax_cloners[SCHEME_PINT_VAL(expr)];
|
||||
if (!f) return NULL;
|
||||
return f((Scheme_Object *)SCHEME_IPTR_VAL(expr), info, delta, closure_depth);
|
||||
return f(dup_ok, (Scheme_Object *)SCHEME_IPTR_VAL(expr), info, delta, closure_depth);
|
||||
}
|
||||
case scheme_application2_type:
|
||||
{
|
||||
|
@ -2575,11 +2707,11 @@ Scheme_Object *scheme_optimize_clone(Scheme_Object *expr, Optimize_Info *info, i
|
|||
app2 = MALLOC_ONE_TAGGED(Scheme_App2_Rec);
|
||||
app2->iso.so.type = scheme_application2_type;
|
||||
|
||||
expr = scheme_optimize_clone(app->rator, info, delta, closure_depth);
|
||||
expr = scheme_optimize_clone(dup_ok, app->rator, info, delta, closure_depth);
|
||||
if (!expr) return NULL;
|
||||
app2->rator = expr;
|
||||
|
||||
expr = scheme_optimize_clone(app->rand, info, delta, closure_depth);
|
||||
expr = scheme_optimize_clone(dup_ok, app->rand, info, delta, closure_depth);
|
||||
if (!expr) return NULL;
|
||||
app2->rand = expr;
|
||||
|
||||
|
@ -2593,7 +2725,7 @@ Scheme_Object *scheme_optimize_clone(Scheme_Object *expr, Optimize_Info *info, i
|
|||
app2 = scheme_malloc_application(app->num_args + 1);
|
||||
|
||||
for (i = app->num_args + 1; i--; ) {
|
||||
expr = scheme_optimize_clone(app->args[i], info, delta, closure_depth);
|
||||
expr = scheme_optimize_clone(dup_ok, app->args[i], info, delta, closure_depth);
|
||||
if (!expr) return NULL;
|
||||
app2->args[i] = expr;
|
||||
}
|
||||
|
@ -2607,15 +2739,15 @@ Scheme_Object *scheme_optimize_clone(Scheme_Object *expr, Optimize_Info *info, i
|
|||
app2 = MALLOC_ONE_TAGGED(Scheme_App3_Rec);
|
||||
app2->iso.so.type = scheme_application3_type;
|
||||
|
||||
expr = scheme_optimize_clone(app->rator, info, delta, closure_depth);
|
||||
expr = scheme_optimize_clone(dup_ok, app->rator, info, delta, closure_depth);
|
||||
if (!expr) return NULL;
|
||||
app2->rator = expr;
|
||||
|
||||
expr = scheme_optimize_clone(app->rand1, info, delta, closure_depth);
|
||||
expr = scheme_optimize_clone(dup_ok, app->rand1, info, delta, closure_depth);
|
||||
if (!expr) return NULL;
|
||||
app2->rand1 = expr;
|
||||
|
||||
expr = scheme_optimize_clone(app->rand2, info, delta, closure_depth);
|
||||
expr = scheme_optimize_clone(dup_ok, app->rand2, info, delta, closure_depth);
|
||||
if (!expr) return NULL;
|
||||
app2->rand2 = expr;
|
||||
|
||||
|
@ -2649,7 +2781,7 @@ Scheme_Object *scheme_optimize_clone(Scheme_Object *expr, Optimize_Info *info, i
|
|||
lv2->position = lv->position;
|
||||
lv2->flags = flags;
|
||||
|
||||
expr = scheme_optimize_clone(lv->value, info, delta, closure_depth + head->count);
|
||||
expr = scheme_optimize_clone(dup_ok, lv->value, info, delta, closure_depth + head->count);
|
||||
if (!expr) return NULL;
|
||||
lv2->value = expr;
|
||||
|
||||
|
@ -2666,7 +2798,7 @@ Scheme_Object *scheme_optimize_clone(Scheme_Object *expr, Optimize_Info *info, i
|
|||
else
|
||||
head2->body = body;
|
||||
|
||||
expr = scheme_optimize_clone(body, info, delta, closure_depth + head->count);
|
||||
expr = scheme_optimize_clone(dup_ok, body, info, delta, closure_depth + head->count);
|
||||
if (!expr) return NULL;
|
||||
|
||||
if (prev)
|
||||
|
@ -2687,7 +2819,7 @@ Scheme_Object *scheme_optimize_clone(Scheme_Object *expr, Optimize_Info *info, i
|
|||
seq2->count = seq->count;
|
||||
|
||||
for (i = seq->count; i--; ) {
|
||||
expr = scheme_optimize_clone(seq->array[i], info, delta, closure_depth);
|
||||
expr = scheme_optimize_clone(dup_ok, seq->array[i], info, delta, closure_depth);
|
||||
if (!expr) return NULL;
|
||||
seq2->array[i] = expr;
|
||||
}
|
||||
|
@ -2701,28 +2833,28 @@ Scheme_Object *scheme_optimize_clone(Scheme_Object *expr, Optimize_Info *info, i
|
|||
b2 = MALLOC_ONE_TAGGED(Scheme_Branch_Rec);
|
||||
b2->so.type = scheme_branch_type;
|
||||
|
||||
expr = scheme_optimize_clone(b->test, info, delta, closure_depth);
|
||||
expr = scheme_optimize_clone(dup_ok, b->test, info, delta, closure_depth);
|
||||
if (!expr) return NULL;
|
||||
b2->test = expr;
|
||||
|
||||
expr = scheme_optimize_clone(b->tbranch, info, delta, closure_depth);
|
||||
expr = scheme_optimize_clone(dup_ok, b->tbranch, info, delta, closure_depth);
|
||||
if (!expr) return NULL;
|
||||
b2->tbranch = expr;
|
||||
|
||||
expr = scheme_optimize_clone(b->fbranch, info, delta, closure_depth);
|
||||
expr = scheme_optimize_clone(dup_ok, b->fbranch, info, delta, closure_depth);
|
||||
if (!expr) return NULL;
|
||||
b2->fbranch = expr;
|
||||
|
||||
return (Scheme_Object *)b2;
|
||||
}
|
||||
case scheme_compiled_unclosed_procedure_type:
|
||||
return scheme_clone_closure_compilation(expr, info, delta, closure_depth);
|
||||
return scheme_clone_closure_compilation(dup_ok, expr, info, delta, closure_depth);
|
||||
case scheme_compiled_toplevel_type:
|
||||
case scheme_compiled_quote_syntax_type:
|
||||
return expr;
|
||||
default:
|
||||
if (t > _scheme_compiled_values_types_) {
|
||||
if (scheme_compiled_duplicate_ok(expr))
|
||||
if (dup_ok || scheme_compiled_duplicate_ok(expr))
|
||||
return expr;
|
||||
}
|
||||
}
|
||||
|
@ -4172,6 +4304,38 @@ scheme_compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env,
|
|||
}
|
||||
}
|
||||
|
||||
static int arg_count(Scheme_Object *lam, Scheme_Comp_Env *env)
|
||||
{
|
||||
Scheme_Object *l, *id, *form = lam;
|
||||
int cnt = 0;
|
||||
DupCheckRecord r;
|
||||
|
||||
lam = SCHEME_STX_CDR(lam);
|
||||
if (!SCHEME_STX_PAIRP(lam)) return -1;
|
||||
|
||||
l = SCHEME_STX_CAR(lam);
|
||||
|
||||
lam = SCHEME_STX_CDR(lam);
|
||||
if (!SCHEME_STX_PAIRP(lam)) return -1;
|
||||
|
||||
while (SCHEME_STX_PAIRP(lam)) { lam = SCHEME_STX_CDR(lam); }
|
||||
if (!SCHEME_STX_NULLP(lam)) return -1;
|
||||
|
||||
|
||||
scheme_begin_dup_symbol_check(&r, env);
|
||||
|
||||
while (SCHEME_STX_PAIRP(l)) {
|
||||
id = SCHEME_STX_CAR(l);
|
||||
scheme_check_identifier("lambda", id, NULL, env, form);
|
||||
scheme_dup_symbol_check(&r, NULL, id, "argument", form);
|
||||
l = SCHEME_STX_CDR(l);
|
||||
cnt++;
|
||||
}
|
||||
if (!SCHEME_STX_NULLP(l)) return -1;
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
static Scheme_Object *
|
||||
compile_expand_app(Scheme_Object *forms, Scheme_Comp_Env *env,
|
||||
Scheme_Compile_Expand_Info *rec, int drec)
|
||||
|
@ -4197,8 +4361,8 @@ compile_expand_app(Scheme_Object *forms, Scheme_Comp_Env *env,
|
|||
form,
|
||||
scheme_sys_wraps(env),
|
||||
0, 2);
|
||||
} else if (!SCHEME_STX_PAIRP(form) /* will end in error */
|
||||
|| SCHEME_STX_SYMBOLP(SCHEME_STX_CAR(form))) {
|
||||
} else if (!SCHEME_STX_PAIRP(form)) {
|
||||
/* will end in error */
|
||||
if (rec[drec].comp)
|
||||
return compile_application(form, env, rec, drec);
|
||||
else {
|
||||
|
@ -4207,90 +4371,146 @@ compile_expand_app(Scheme_Object *forms, Scheme_Comp_Env *env,
|
|||
/* naya will be prefixed and returned... */
|
||||
}
|
||||
} else if (rec[drec].comp) {
|
||||
Scheme_Object *name;
|
||||
Scheme_Object *name, *origname, *gval, *orig_rest_form, *rest_form;
|
||||
name = SCHEME_STX_CAR(form);
|
||||
origname = name;
|
||||
|
||||
name = scheme_check_immediate_macro(name, env, rec, drec, 0, &gval, NULL, NULL);
|
||||
|
||||
/* look for ((lambda (x) ...) ...); */
|
||||
/* rator as a macro has to be a parenthesized expr, otherwise the
|
||||
parens for application would have been the macro call. */
|
||||
if (SCHEME_STX_PAIRP(name) && SCHEME_STX_SYMBOLP(SCHEME_STX_CAR(name))) {
|
||||
Scheme_Object *gval, *origname = name;
|
||||
|
||||
name = scheme_check_immediate_macro(name, env, rec, drec, 0, &gval, NULL, NULL);
|
||||
|
||||
if (SAME_OBJ(gval, scheme_lambda_syntax)) {
|
||||
Scheme_Object *argsnbody;
|
||||
if (SAME_OBJ(gval, scheme_lambda_syntax)) {
|
||||
Scheme_Object *argsnbody;
|
||||
|
||||
argsnbody = SCHEME_STX_CDR(name);
|
||||
if (SCHEME_STX_PAIRP(argsnbody)) {
|
||||
Scheme_Object *args, *body;
|
||||
argsnbody = SCHEME_STX_CDR(name);
|
||||
if (SCHEME_STX_PAIRP(argsnbody)) {
|
||||
Scheme_Object *args, *body;
|
||||
|
||||
args = SCHEME_STX_CAR(argsnbody);
|
||||
body = SCHEME_STX_CDR(argsnbody);
|
||||
args = SCHEME_STX_CAR(argsnbody);
|
||||
body = SCHEME_STX_CDR(argsnbody);
|
||||
|
||||
if (SCHEME_STX_PAIRP(body)) {
|
||||
int pl;
|
||||
pl = scheme_stx_proper_list_length(args);
|
||||
if (pl >= 0) {
|
||||
Scheme_Object *bindings = scheme_null, *last = NULL;
|
||||
Scheme_Object *rest;
|
||||
int al;
|
||||
if (SCHEME_STX_PAIRP(body)) {
|
||||
int pl;
|
||||
pl = scheme_stx_proper_list_length(args);
|
||||
if (pl >= 0) {
|
||||
Scheme_Object *bindings = scheme_null, *last = NULL;
|
||||
Scheme_Object *rest;
|
||||
int al;
|
||||
|
||||
rest = SCHEME_STX_CDR(form);
|
||||
al = scheme_stx_proper_list_length(rest);
|
||||
rest = SCHEME_STX_CDR(form);
|
||||
al = scheme_stx_proper_list_length(rest);
|
||||
|
||||
if (al == pl) {
|
||||
DupCheckRecord r;
|
||||
if (al == pl) {
|
||||
DupCheckRecord r;
|
||||
|
||||
scheme_begin_dup_symbol_check(&r, env);
|
||||
scheme_begin_dup_symbol_check(&r, env);
|
||||
|
||||
while (!SCHEME_STX_NULLP(args)) {
|
||||
Scheme_Object *v, *n;
|
||||
while (!SCHEME_STX_NULLP(args)) {
|
||||
Scheme_Object *v, *n;
|
||||
|
||||
n = SCHEME_STX_CAR(args);
|
||||
scheme_check_identifier("lambda", n, NULL, env, name);
|
||||
n = SCHEME_STX_CAR(args);
|
||||
scheme_check_identifier("lambda", n, NULL, env, name);
|
||||
|
||||
/* If we don't check here, the error is in terms of `let': */
|
||||
scheme_dup_symbol_check(&r, NULL, n, "argument", name);
|
||||
/* If we don't check here, the error is in terms of `let': */
|
||||
scheme_dup_symbol_check(&r, NULL, n, "argument", name);
|
||||
|
||||
v = SCHEME_STX_CAR(rest);
|
||||
v = cons(cons(cons(n, scheme_null), cons(v, scheme_null)), scheme_null);
|
||||
if (last)
|
||||
SCHEME_CDR(last) = v;
|
||||
else
|
||||
bindings = v;
|
||||
v = SCHEME_STX_CAR(rest);
|
||||
v = cons(cons(cons(n, scheme_null), cons(v, scheme_null)), scheme_null);
|
||||
if (last)
|
||||
SCHEME_CDR(last) = v;
|
||||
else
|
||||
bindings = v;
|
||||
|
||||
last = v;
|
||||
args = SCHEME_STX_CDR(args);
|
||||
rest = SCHEME_STX_CDR(rest);
|
||||
}
|
||||
last = v;
|
||||
args = SCHEME_STX_CDR(args);
|
||||
rest = SCHEME_STX_CDR(rest);
|
||||
}
|
||||
|
||||
body = scheme_datum_to_syntax(cons(let_values_symbol,
|
||||
cons(bindings,
|
||||
body)),
|
||||
form,
|
||||
scheme_sys_wraps(env),
|
||||
0, 2);
|
||||
body = scheme_datum_to_syntax(cons(let_values_symbol,
|
||||
cons(bindings,
|
||||
body)),
|
||||
form,
|
||||
scheme_sys_wraps(env),
|
||||
0, 2);
|
||||
|
||||
/* Copy certifications from lambda to `body'. */
|
||||
body = scheme_stx_cert(body, NULL, NULL, name, NULL, 1);
|
||||
/* Copy certifications from lambda to `body'. */
|
||||
body = scheme_stx_cert(body, NULL, NULL, name, NULL, 1);
|
||||
|
||||
return scheme_compile_expand_expr(body, env, rec, drec, 0);
|
||||
} else {
|
||||
return scheme_compile_expand_expr(body, env, rec, drec, 0);
|
||||
} else {
|
||||
#if 0
|
||||
scheme_wrong_syntax(scheme_application_stx_string, NULL, form,
|
||||
"procedure application: bad ((lambda (...) ...) ...) syntax");
|
||||
return NULL;
|
||||
scheme_wrong_syntax(scheme_application_stx_string, NULL, form,
|
||||
"procedure application: bad ((lambda (...) ...) ...) syntax");
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NOT_SAME_OBJ(name, origname)) {
|
||||
form = SCHEME_STX_CDR(form);
|
||||
form = scheme_datum_to_syntax(scheme_make_immutable_pair(name, form), forms, forms, 0, 2);
|
||||
orig_rest_form = SCHEME_STX_CDR(form);
|
||||
|
||||
/* Look for (call-with-values (lambda () M) (lambda (id ...) N)) */
|
||||
if (SCHEME_STX_SYMBOLP(name)) {
|
||||
Scheme_Object *at_first, *at_second, *the_end, *cwv_stx;
|
||||
at_first = SCHEME_STX_CDR(form);
|
||||
if (SCHEME_STX_PAIRP(at_first)) {
|
||||
at_second = SCHEME_STX_CDR(at_first);
|
||||
if (SCHEME_STX_PAIRP(at_second)) {
|
||||
the_end = SCHEME_STX_CDR(at_second);
|
||||
if (SCHEME_STX_NULLP(the_end)) {
|
||||
Scheme_Object *orig_at_second = at_second;
|
||||
|
||||
cwv_stx = scheme_datum_to_syntax(scheme_intern_symbol("call-with-values"),
|
||||
scheme_false, scheme_sys_wraps(env), 0, 0);
|
||||
if (scheme_stx_module_eq(name, cwv_stx, 0)) {
|
||||
Scheme_Object *first, *orig_first;
|
||||
orig_first = SCHEME_STX_CAR(at_first);
|
||||
first = scheme_check_immediate_macro(orig_first, env, rec, drec, 0, &gval, NULL, NULL);
|
||||
if (SAME_OBJ(gval, scheme_lambda_syntax)
|
||||
&& SCHEME_STX_PAIRP(first)
|
||||
&& (arg_count(first, env) == 0)) {
|
||||
Scheme_Object *second, *orig_second;
|
||||
orig_second = SCHEME_STX_CAR(at_second);
|
||||
second = scheme_check_immediate_macro(orig_second, env, rec, drec, 0, &gval, NULL, NULL);
|
||||
if (SAME_OBJ(gval, scheme_lambda_syntax)
|
||||
&& SCHEME_STX_PAIRP(second)
|
||||
&& (arg_count(second, env) >= 0)) {
|
||||
Scheme_Object *lhs;
|
||||
second = SCHEME_STX_CDR(second);
|
||||
lhs = SCHEME_STX_CAR(second);
|
||||
second = SCHEME_STX_CDR(second);
|
||||
first = SCHEME_STX_CDR(first);
|
||||
first = SCHEME_STX_CDR(first);
|
||||
/* Convert to let-values: */
|
||||
name = icons(let_values_symbol,
|
||||
icons(icons(icons(lhs, icons(icons(begin_symbol, first),
|
||||
scheme_null)),
|
||||
scheme_null),
|
||||
second));
|
||||
form = scheme_datum_to_syntax(name, forms, scheme_sys_wraps(env), 0, 2);
|
||||
return scheme_compile_expand_expr(form, env, rec, drec, 0);
|
||||
}
|
||||
if (!SAME_OBJ(second, orig_second)) {
|
||||
at_second = scheme_datum_to_syntax(icons(second, the_end), at_second, at_second, 0, 2);
|
||||
}
|
||||
}
|
||||
if (!SAME_OBJ(first, orig_first)
|
||||
|| !SAME_OBJ(at_second, orig_at_second)) {
|
||||
at_first = scheme_datum_to_syntax(icons(first, at_second), at_first, at_first, 0, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rest_form = at_first;
|
||||
} else {
|
||||
rest_form = orig_rest_form;
|
||||
}
|
||||
|
||||
if (NOT_SAME_OBJ(name, origname)
|
||||
|| NOT_SAME_OBJ(rest_form, orig_rest_form)) {
|
||||
form = scheme_datum_to_syntax(scheme_make_immutable_pair(name, rest_form), forms, forms, 0, 2);
|
||||
}
|
||||
|
||||
return compile_application(form, env, rec, drec);
|
||||
|
@ -6468,7 +6688,7 @@ static void *eval_k(void)
|
|||
Scheme_Thread *p = scheme_current_thread;
|
||||
Scheme_Object *v, **save_runstack;
|
||||
Scheme_Env *env;
|
||||
int isexpr, multi, use_jit;
|
||||
int isexpr, multi, use_jit, as_tail;
|
||||
|
||||
v = (Scheme_Object *)p->ku.k.p1;
|
||||
env = (Scheme_Env *)p->ku.k.p2;
|
||||
|
@ -6476,6 +6696,7 @@ static void *eval_k(void)
|
|||
p->ku.k.p2 = NULL;
|
||||
multi = p->ku.k.i1;
|
||||
isexpr = p->ku.k.i2;
|
||||
as_tail = p->ku.k.i3;
|
||||
|
||||
{
|
||||
Scheme_Object *b;
|
||||
|
@ -6508,7 +6729,30 @@ static void *eval_k(void)
|
|||
|
||||
save_runstack = scheme_push_prefix(env, top->prefix, NULL, NULL, 0, env->phase);
|
||||
|
||||
if (multi)
|
||||
if (as_tail) {
|
||||
/* Cons up a closure to capture the prefix */
|
||||
Scheme_Closure_Data *data;
|
||||
mzshort *map;
|
||||
int i, sz;
|
||||
|
||||
sz = (save_runstack XFORM_OK_MINUS MZ_RUNSTACK);
|
||||
map = (mzshort *)scheme_malloc_atomic(sizeof(mzshort) * sz);
|
||||
for (i = 0; i < sz; i++) {
|
||||
map[i] = i;
|
||||
}
|
||||
|
||||
data = MALLOC_ONE_TAGGED(Scheme_Closure_Data);
|
||||
data->iso.so.type = scheme_compiled_unclosed_procedure_type;
|
||||
data->num_params = 0;
|
||||
data->max_let_depth = top->max_let_depth + sz;
|
||||
data->closure_size = sz;
|
||||
data->closure_map = map;
|
||||
data->code = v;
|
||||
|
||||
v = scheme_make_closure(p, (Scheme_Object *)data, 1);
|
||||
|
||||
v = _scheme_tail_apply(v, 0, NULL);
|
||||
} else if (multi)
|
||||
v = _scheme_eval_linked_expr_multi_wp(v, p);
|
||||
else
|
||||
v = _scheme_eval_linked_expr_wp(v, p);
|
||||
|
@ -6522,7 +6766,7 @@ static void *eval_k(void)
|
|||
}
|
||||
|
||||
static Scheme_Object *_eval(Scheme_Object *obj, Scheme_Env *env,
|
||||
int isexpr, int multi, int top)
|
||||
int isexpr, int multi, int top, int as_tail)
|
||||
{
|
||||
Scheme_Thread *p = scheme_current_thread;
|
||||
|
||||
|
@ -6530,6 +6774,7 @@ static Scheme_Object *_eval(Scheme_Object *obj, Scheme_Env *env,
|
|||
p->ku.k.p2 = env;
|
||||
p->ku.k.i1 = multi;
|
||||
p->ku.k.i2 = isexpr;
|
||||
p->ku.k.i3 = as_tail;
|
||||
|
||||
if (top)
|
||||
return (Scheme_Object *)scheme_top_level_do(eval_k, 1);
|
||||
|
@ -6539,32 +6784,32 @@ static Scheme_Object *_eval(Scheme_Object *obj, Scheme_Env *env,
|
|||
|
||||
Scheme_Object *scheme_eval_compiled(Scheme_Object *obj, Scheme_Env *env)
|
||||
{
|
||||
return _eval(obj, env, 0, 0, 1);
|
||||
return _eval(obj, env, 0, 0, 1, 0);
|
||||
}
|
||||
|
||||
Scheme_Object *scheme_eval_compiled_multi(Scheme_Object *obj, Scheme_Env *env)
|
||||
{
|
||||
return _eval(obj, env, 0, 1, 1);
|
||||
return _eval(obj, env, 0, 1, 1, 0);
|
||||
}
|
||||
|
||||
Scheme_Object *_scheme_eval_compiled(Scheme_Object *obj, Scheme_Env *env)
|
||||
{
|
||||
return _eval(obj, env, 0, 0, 0);
|
||||
return _eval(obj, env, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
Scheme_Object *_scheme_eval_compiled_multi(Scheme_Object *obj, Scheme_Env *env)
|
||||
{
|
||||
return _eval(obj, env, 0, 1, 0);
|
||||
return _eval(obj, env, 0, 1, 0, 0);
|
||||
}
|
||||
|
||||
Scheme_Object *scheme_eval_linked_expr(Scheme_Object *obj)
|
||||
{
|
||||
return _eval(obj, NULL, 1, 0, 1);
|
||||
return _eval(obj, NULL, 1, 0, 1, 0);
|
||||
}
|
||||
|
||||
Scheme_Object *scheme_eval_linked_expr_multi(Scheme_Object *obj)
|
||||
{
|
||||
return _eval(obj, NULL, 1, 1, 1);
|
||||
return _eval(obj, NULL, 1, 1, 1, 0);
|
||||
}
|
||||
|
||||
/* for mzc: */
|
||||
|
@ -6713,34 +6958,16 @@ Scheme_Object *scheme_tail_eval_expr(Scheme_Object *obj)
|
|||
return scheme_tail_eval(obj);
|
||||
}
|
||||
|
||||
static Scheme_Object *
|
||||
do_default_eval_handler(Scheme_Env *env, int argc, Scheme_Object **argv)
|
||||
{
|
||||
Scheme_Object *v;
|
||||
|
||||
v = _compile(argv[0], env, 0, 1, 0, 0);
|
||||
|
||||
return _eval(v, env, 0, 1, 0);
|
||||
}
|
||||
|
||||
static Scheme_Object *
|
||||
do_default_compile_handler(Scheme_Env *env, int argc, Scheme_Object **argv)
|
||||
{
|
||||
return _compile(argv[0], env, SCHEME_FALSEP(argv[1]), 0, 0, 0);
|
||||
}
|
||||
|
||||
/* local functions */
|
||||
|
||||
static Scheme_Object *
|
||||
sch_eval(const char *who, int argc, Scheme_Object *argv[])
|
||||
{
|
||||
if (argc == 1) {
|
||||
return _scheme_apply_multi(scheme_get_param(scheme_current_config(), MZCONFIG_EVAL_HANDLER),
|
||||
1, argv);
|
||||
return _scheme_tail_apply(scheme_get_param(scheme_current_config(), MZCONFIG_EVAL_HANDLER),
|
||||
1, argv);
|
||||
} else {
|
||||
Scheme_Config *config;
|
||||
Scheme_Cont_Frame_Data cframe;
|
||||
Scheme_Object *v;
|
||||
|
||||
if (SCHEME_TYPE(argv[1]) != scheme_namespace_type)
|
||||
scheme_wrong_type(who, "namespace", 1, argc, argv);
|
||||
|
@ -6748,15 +6975,10 @@ sch_eval(const char *who, int argc, Scheme_Object *argv[])
|
|||
config = scheme_extend_config(scheme_current_config(),
|
||||
MZCONFIG_ENV,
|
||||
argv[1]);
|
||||
scheme_push_continuation_frame(&cframe);
|
||||
scheme_set_cont_mark(scheme_parameterization_key, (Scheme_Object *)config);
|
||||
|
||||
v = _scheme_apply_multi(scheme_get_param(config, MZCONFIG_EVAL_HANDLER),
|
||||
1, argv);
|
||||
|
||||
scheme_pop_continuation_frame(&cframe);
|
||||
|
||||
return v;
|
||||
return _scheme_tail_apply(scheme_get_param(config, MZCONFIG_EVAL_HANDLER),
|
||||
1, argv);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6799,16 +7021,24 @@ Scheme_Object *
|
|||
scheme_default_eval_handler(int argc, Scheme_Object **argv)
|
||||
{
|
||||
Scheme_Env *env;
|
||||
Scheme_Object *v;
|
||||
|
||||
env = scheme_get_env(NULL);
|
||||
return do_default_eval_handler(env, argc, argv);
|
||||
|
||||
v = _compile(argv[0], env, 0, 1, 0, 0);
|
||||
|
||||
/* Returns a tail apply: */
|
||||
return _eval(v, env, 0, 1, 0, 1);
|
||||
}
|
||||
|
||||
Scheme_Object *
|
||||
scheme_default_compile_handler(int argc, Scheme_Object **argv)
|
||||
{
|
||||
Scheme_Env *env;
|
||||
|
||||
env = scheme_get_env(NULL);
|
||||
return do_default_compile_handler(env, argc, argv);
|
||||
|
||||
return _compile(argv[0], env, SCHEME_FALSEP(argv[1]), 0, 0, 0);
|
||||
}
|
||||
|
||||
static Scheme_Object *
|
||||
|
@ -7416,6 +7646,9 @@ void scheme_pop_prefix(Scheme_Object **rs)
|
|||
where the abstract values are "not available", "value", "boxed
|
||||
value", "syntax object", or "global array". */
|
||||
|
||||
/* FIXME: validation doesn't check CLOS_SINGLE_RESULT or
|
||||
CLOS_PRESERVES_MARKS. (Maybe check them in the JIT pass?) */
|
||||
|
||||
#define VALID_NOT 0
|
||||
#define VALID_VAL 1
|
||||
#define VALID_BOX 2
|
||||
|
|
|
@ -72,6 +72,7 @@ int scheme_defining_primitives; /* set to 1 during start-up */
|
|||
Scheme_Object scheme_void[1]; /* the void constant */
|
||||
Scheme_Object *scheme_values_func; /* the function bound to `values' */
|
||||
Scheme_Object *scheme_void_proc;
|
||||
Scheme_Object *scheme_call_with_values_proc; /* the function bound to `call-with-values' */
|
||||
|
||||
Scheme_Object *scheme_tail_call_waiting;
|
||||
|
||||
|
@ -221,11 +222,14 @@ scheme_init_fun (Scheme_Env *env)
|
|||
"ormap",
|
||||
2, -1),
|
||||
env);
|
||||
|
||||
REGISTER_SO(scheme_call_with_values_proc);
|
||||
scheme_call_with_values_proc = scheme_make_prim_w_arity2(call_with_values,
|
||||
"call-with-values",
|
||||
2, 2,
|
||||
0, -1);
|
||||
scheme_add_global_constant("call-with-values",
|
||||
scheme_make_prim_w_arity2(call_with_values,
|
||||
"call-with-values",
|
||||
2, 2,
|
||||
0, -1),
|
||||
scheme_call_with_values_proc,
|
||||
env);
|
||||
|
||||
REGISTER_SO(scheme_values_func);
|
||||
|
@ -796,6 +800,9 @@ scheme_optimize_closure_compilation(Scheme_Object *_data, Optimize_Info *info)
|
|||
|
||||
data = (Scheme_Closure_Data *)_data;
|
||||
|
||||
info->single_result = 1;
|
||||
info->preserves_marks = 1;
|
||||
|
||||
info = scheme_optimize_info_add_frame(info, data->num_params, data->num_params,
|
||||
SCHEME_LAMBDA_FRAME);
|
||||
|
||||
|
@ -807,6 +814,16 @@ scheme_optimize_closure_compilation(Scheme_Object *_data, Optimize_Info *info)
|
|||
|
||||
code = scheme_optimize_expr(data->code, info);
|
||||
|
||||
if (info->single_result)
|
||||
SCHEME_CLOSURE_DATA_FLAGS(data) |= CLOS_SINGLE_RESULT;
|
||||
else if (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_SINGLE_RESULT)
|
||||
SCHEME_CLOSURE_DATA_FLAGS(data) -= CLOS_SINGLE_RESULT;
|
||||
|
||||
if (info->preserves_marks)
|
||||
SCHEME_CLOSURE_DATA_FLAGS(data) |= CLOS_PRESERVES_MARKS;
|
||||
else if (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_PRESERVES_MARKS)
|
||||
SCHEME_CLOSURE_DATA_FLAGS(data) -= CLOS_PRESERVES_MARKS;
|
||||
|
||||
data->code = code;
|
||||
|
||||
/* Remembers positions of used vars (and unsets usage for this level) */
|
||||
|
@ -828,7 +845,7 @@ scheme_optimize_closure_compilation(Scheme_Object *_data, Optimize_Info *info)
|
|||
return (Scheme_Object *)data;
|
||||
}
|
||||
|
||||
Scheme_Object *scheme_clone_closure_compilation(Scheme_Object *_data, Optimize_Info *info, int delta, int closure_depth)
|
||||
Scheme_Object *scheme_clone_closure_compilation(int dup_ok, Scheme_Object *_data, Optimize_Info *info, int delta, int closure_depth)
|
||||
{
|
||||
Scheme_Closure_Data *data, *data2;
|
||||
Scheme_Object *body;
|
||||
|
@ -837,7 +854,7 @@ Scheme_Object *scheme_clone_closure_compilation(Scheme_Object *_data, Optimize_I
|
|||
|
||||
data = (Scheme_Closure_Data *)_data;
|
||||
|
||||
body = scheme_optimize_clone(data->code, info, delta, closure_depth + data->num_params);
|
||||
body = scheme_optimize_clone(dup_ok, data->code, info, delta, closure_depth + data->num_params);
|
||||
if (!body) return NULL;
|
||||
|
||||
data2 = MALLOC_ONE_TAGGED(Scheme_Closure_Data);
|
||||
|
@ -1951,6 +1968,10 @@ scheme_apply_multi_no_eb(Scheme_Object *rator, int num_rands, Scheme_Object **ra
|
|||
Scheme_Object *
|
||||
scheme_tail_apply (Scheme_Object *rator, int num_rands, Scheme_Object **rands)
|
||||
{
|
||||
/* NOTE: apply_values_execute (in syntax.c) and
|
||||
tail_call_with_values_from_multiple_result (in jit.c)
|
||||
assume that this function won't allocate when
|
||||
num_rands <= p->tail_buffer_size. */
|
||||
int i;
|
||||
Scheme_Thread *p = scheme_current_thread;
|
||||
|
||||
|
@ -2984,173 +3005,37 @@ apply(int argc, Scheme_Object *argv[])
|
|||
return SCHEME_TAIL_CALL_WAITING;
|
||||
}
|
||||
|
||||
static Scheme_Object *
|
||||
do_map(int argc, Scheme_Object *argv[], char *name, int make_result,
|
||||
int and_mode, int or_mode)
|
||||
/* common code for `map', `for-each', `andmap' and `ormap' */
|
||||
{
|
||||
# define NUM_QUICK_ARGS 3
|
||||
# define NUM_QUICK_RES 5
|
||||
int i, size = 0, l, pos;
|
||||
int can_multi;
|
||||
Scheme_Object *quick1[NUM_QUICK_ARGS], *quick2[NUM_QUICK_ARGS];
|
||||
Scheme_Object *quick3[NUM_QUICK_RES], **working, **args, **resarray;
|
||||
Scheme_Object *v, *retval;
|
||||
int cc;
|
||||
#define DO_MAP map
|
||||
#define MAP_NAME "map"
|
||||
#define MAP_MODE
|
||||
#include "schmap.inc"
|
||||
#undef MAP_MODE
|
||||
#undef MAP_NAME
|
||||
#undef DO_MAP
|
||||
|
||||
can_multi = (!make_result && !and_mode && !or_mode);
|
||||
#define DO_MAP for_each
|
||||
#define MAP_NAME "for-each"
|
||||
#define FOR_EACH_MODE
|
||||
#include "schmap.inc"
|
||||
#undef FOR_EACH_MODE
|
||||
#undef MAP_NAME
|
||||
#undef DO_MAP
|
||||
|
||||
if (!SCHEME_PROCP(argv[0]))
|
||||
scheme_wrong_type(name, "procedure", 0, argc, argv);
|
||||
#define DO_MAP andmap
|
||||
#define MAP_NAME "andmap"
|
||||
#define AND_MODE
|
||||
#include "schmap.inc"
|
||||
#undef AND_MODE
|
||||
#undef MAP_NAME
|
||||
#undef DO_MAP
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (!SCHEME_LISTP (argv[i]))
|
||||
scheme_wrong_type(name, "list", i, argc, argv);
|
||||
|
||||
l = scheme_proper_list_length(argv[i]);
|
||||
|
||||
if (l < 0)
|
||||
scheme_wrong_type(name, "proper list", i, argc, argv);
|
||||
|
||||
if (i == 1)
|
||||
size = l;
|
||||
else if (size != l) {
|
||||
char *argstr;
|
||||
long alen;
|
||||
|
||||
argstr = scheme_make_args_string("", -1, argc, argv, &alen);
|
||||
|
||||
scheme_raise_exn(MZEXN_FAIL_CONTRACT,
|
||||
"%s: all lists must have same size%t",
|
||||
name, argstr, alen);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (SCHEME_FALSEP(scheme_get_or_check_arity(argv[0], argc - 1))) {
|
||||
char *s;
|
||||
long aelen;
|
||||
|
||||
s = scheme_make_arity_expect_string(argv[0], argc - 1, NULL, &aelen);
|
||||
|
||||
scheme_raise_exn(MZEXN_FAIL_CONTRACT,
|
||||
"%s: arity mismatch for %t", name,
|
||||
s, aelen);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (argc <= (NUM_QUICK_ARGS + 1)) {
|
||||
args = quick1;
|
||||
working = quick2;
|
||||
} else {
|
||||
args = MALLOC_N(Scheme_Object *, argc - 1);
|
||||
working = MALLOC_N(Scheme_Object *, argc - 1);
|
||||
}
|
||||
|
||||
if (size <= NUM_QUICK_RES) {
|
||||
resarray = quick3;
|
||||
} else {
|
||||
if (make_result)
|
||||
resarray = MALLOC_N(Scheme_Object *, size);
|
||||
else
|
||||
resarray = NULL;
|
||||
}
|
||||
|
||||
/* Copy argc into working array */
|
||||
for (i = 1; i < argc; i++) {
|
||||
working[i-1] = argv[i];
|
||||
}
|
||||
|
||||
--argc;
|
||||
|
||||
if (and_mode)
|
||||
retval = scheme_true;
|
||||
else if (or_mode)
|
||||
retval = scheme_false;
|
||||
else
|
||||
retval = scheme_void;
|
||||
|
||||
pos = 0;
|
||||
while (pos < size) {
|
||||
/* collect args to apply */
|
||||
for (i = 0; i < argc ; i++) {
|
||||
if (!SCHEME_PAIRP(working[i])) {
|
||||
/* There was a mutation! */
|
||||
scheme_raise_exn(MZEXN_FAIL_CONTRACT,
|
||||
"%s: argument list mutated",
|
||||
name);
|
||||
return NULL;
|
||||
}
|
||||
args[i] = SCHEME_CAR(working[i]);
|
||||
working[i] = SCHEME_CDR(working[i]);
|
||||
}
|
||||
|
||||
cc = scheme_cont_capture_count;
|
||||
|
||||
if (can_multi)
|
||||
v = _scheme_apply_multi(argv[0], argc, args);
|
||||
else
|
||||
v = _scheme_apply(argv[0], argc, args);
|
||||
|
||||
if (cc != scheme_cont_capture_count) {
|
||||
/* Copy arrays to avoid messing with other continuations */
|
||||
if (make_result && (size > NUM_QUICK_RES)) {
|
||||
Scheme_Object **naya;
|
||||
naya = MALLOC_N(Scheme_Object *, size);
|
||||
memcpy(naya, resarray, pos * sizeof(Scheme_Object *));
|
||||
resarray = naya;
|
||||
}
|
||||
if (argc > NUM_QUICK_ARGS) {
|
||||
Scheme_Object **naya;
|
||||
args = MALLOC_N(Scheme_Object *, argc);
|
||||
naya = MALLOC_N(Scheme_Object *, argc);
|
||||
memcpy(naya, working, argc * sizeof(Scheme_Object *));
|
||||
working = naya;
|
||||
}
|
||||
}
|
||||
|
||||
if (make_result) {
|
||||
resarray[pos] = v;
|
||||
} else if (and_mode) {
|
||||
if (SCHEME_FALSEP(v))
|
||||
return scheme_false;
|
||||
retval = v;
|
||||
} else if (or_mode) {
|
||||
if (SCHEME_TRUEP(v))
|
||||
return v;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
|
||||
if (make_result)
|
||||
retval = scheme_build_list(size, resarray);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static Scheme_Object *
|
||||
map (int argc, Scheme_Object *argv[])
|
||||
{
|
||||
return do_map(argc, argv, "map", 1, 0, 0);
|
||||
}
|
||||
|
||||
static Scheme_Object *
|
||||
for_each (int argc, Scheme_Object *argv[])
|
||||
{
|
||||
return do_map(argc, argv, "for-each", 0, 0, 0);
|
||||
}
|
||||
|
||||
static Scheme_Object *
|
||||
andmap(int argc, Scheme_Object *argv[])
|
||||
{
|
||||
return do_map(argc, argv, "andmap", 0, 1, 0);
|
||||
}
|
||||
|
||||
static Scheme_Object *
|
||||
ormap(int argc, Scheme_Object *argv[])
|
||||
{
|
||||
return do_map(argc, argv, "ormap", 0, 0, 1);
|
||||
}
|
||||
#define DO_MAP ormap
|
||||
#define MAP_NAME "ormap"
|
||||
#define OR_MODE
|
||||
#include "schmap.inc"
|
||||
#undef OR_MODE
|
||||
#undef MAP_NAME
|
||||
#undef DO_MAP
|
||||
|
||||
static Scheme_Object *call_with_values(int argc, Scheme_Object *argv[])
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -108,7 +108,7 @@ struct jit_local_state {
|
|||
#define _jit_bra_l(rs, is, op) (CMPQir(is, rs), op, _jit.x.pc)
|
||||
|
||||
#ifdef JIT_X86_64
|
||||
# define jit_bra_l(rs, is, op) (_u32P((long)(is)) \
|
||||
# define jit_bra_l(rs, is, op) (_s32P((long)(is)) \
|
||||
? _jit_bra_l(rs, is, op) \
|
||||
: (jit_movi_l(JIT_REXTMP, is), jit_bra_qr(JIT_REXTMP, rs, op)))
|
||||
#else
|
||||
|
|
|
@ -53,10 +53,6 @@ static Scheme_Object *member (int argc, Scheme_Object *argv[]);
|
|||
static Scheme_Object *assv (int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *assq (int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *assoc (int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *caar_prim (int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *cadr_prim (int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *cdar_prim (int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *cddr_prim (int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *caaar_prim (int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *caadr_prim (int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *cadar_prim (int argc, Scheme_Object *argv[]);
|
||||
|
@ -257,26 +253,23 @@ scheme_init_list (Scheme_Env *env)
|
|||
"assoc",
|
||||
2, 2),
|
||||
env);
|
||||
scheme_add_global_constant ("caar",
|
||||
scheme_make_noncm_prim(caar_prim,
|
||||
"caar",
|
||||
1, 1),
|
||||
env);
|
||||
scheme_add_global_constant ("cadr",
|
||||
scheme_make_noncm_prim(cadr_prim,
|
||||
"cadr",
|
||||
1, 1),
|
||||
env);
|
||||
scheme_add_global_constant ("cdar",
|
||||
scheme_make_noncm_prim(cdar_prim,
|
||||
"cdar",
|
||||
1, 1),
|
||||
env);
|
||||
scheme_add_global_constant ("cddr",
|
||||
scheme_make_noncm_prim(cddr_prim,
|
||||
"cddr",
|
||||
1, 1),
|
||||
env);
|
||||
|
||||
p = scheme_make_noncm_prim(scheme_checked_caar, "caar", 1, 1);
|
||||
SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED;
|
||||
scheme_add_global_constant ("caar", p, env);
|
||||
|
||||
p = scheme_make_noncm_prim(scheme_checked_cadr, "cadr", 1, 1);
|
||||
SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED;
|
||||
scheme_add_global_constant ("cadr", p, env);
|
||||
|
||||
p = scheme_make_noncm_prim(scheme_checked_cdar, "cdar", 1, 1);
|
||||
SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED;
|
||||
scheme_add_global_constant ("cdar", p, env);
|
||||
|
||||
p = scheme_make_noncm_prim(scheme_checked_cddr, "cddr", 1, 1);
|
||||
SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED;
|
||||
scheme_add_global_constant ("cddr", p, env);
|
||||
|
||||
scheme_add_global_constant ("caaar",
|
||||
scheme_make_noncm_prim(caaar_prim,
|
||||
"caaar",
|
||||
|
@ -1223,8 +1216,8 @@ GEN_ASS(assq, assq, SAME_OBJ)
|
|||
GEN_ASS(assoc, assoc, scheme_equal)
|
||||
|
||||
#define LISTFUNC2(name, C, D) \
|
||||
static Scheme_Object * \
|
||||
name ## _prim (int argc, Scheme_Object *argv[]) \
|
||||
Scheme_Object * \
|
||||
scheme_checked_ ## name (int argc, Scheme_Object *argv[]) \
|
||||
{ \
|
||||
if (!(SCHEME_PAIRP(argv[0]) \
|
||||
&& SCHEME_PAIRP(D(argv[0])))) \
|
||||
|
|
|
@ -3176,11 +3176,41 @@ static void module_validate(Scheme_Object *data, Mz_CPort *port,
|
|||
/* FIXME: validate exp-time code */
|
||||
}
|
||||
|
||||
static int set_code_closure_flags(Scheme_Object *clones,
|
||||
int set_flags, int mask_flags)
|
||||
{
|
||||
Scheme_Object *clone, *orig, *first;
|
||||
Scheme_Closure_Data *data;
|
||||
int flags = CLOS_SINGLE_RESULT | CLOS_PRESERVES_MARKS;
|
||||
|
||||
/* The first in a clone pair is the one that is consulted for
|
||||
references. The second one is the original, and its the one whose
|
||||
flags are updated by optimization. So consult the original, and set
|
||||
flags in both. */
|
||||
|
||||
while (clones) {
|
||||
first = SCHEME_CAR(clones);
|
||||
clone = SCHEME_CAR(first);
|
||||
orig = SCHEME_CDR(first);
|
||||
|
||||
data = (Scheme_Closure_Data *)orig;
|
||||
flags = (flags & SCHEME_CLOSURE_DATA_FLAGS(data));
|
||||
SCHEME_CLOSURE_DATA_FLAGS(data) = set_flags | (SCHEME_CLOSURE_DATA_FLAGS(data) & mask_flags);
|
||||
data = (Scheme_Closure_Data *)clone;
|
||||
SCHEME_CLOSURE_DATA_FLAGS(data) = set_flags | (SCHEME_CLOSURE_DATA_FLAGS(data) & mask_flags);
|
||||
|
||||
clones = SCHEME_CDR(clones);
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static Scheme_Object *
|
||||
module_optimize(Scheme_Object *data, Optimize_Info *info)
|
||||
{
|
||||
Scheme_Module *m = (Scheme_Module *)data;
|
||||
Scheme_Object *e, *b, *vars, *start_simltaneous_b;
|
||||
Scheme_Object *cl_first = NULL, *cl_last = NULL;
|
||||
Scheme_Hash_Table *consts = NULL, *ready_table = NULL;
|
||||
int cont;
|
||||
|
||||
|
@ -3215,7 +3245,16 @@ module_optimize(Scheme_Object *data, Optimize_Info *info)
|
|||
Scheme_Object *e2;
|
||||
|
||||
if (SAME_TYPE(SCHEME_TYPE(e), scheme_compiled_unclosed_procedure_type)) {
|
||||
e2 = scheme_optimize_clone(e, info, 0, 0);
|
||||
e2 = scheme_optimize_clone(1, e, info, 0, 0);
|
||||
if (e2) {
|
||||
Scheme_Object *pr;
|
||||
pr = scheme_make_raw_pair(scheme_make_raw_pair(e2, e), NULL);
|
||||
if (cl_last)
|
||||
SCHEME_CDR(cl_last) = pr;
|
||||
else
|
||||
cl_first = pr;
|
||||
cl_last = pr;
|
||||
}
|
||||
} else {
|
||||
e2 = e;
|
||||
}
|
||||
|
@ -3272,6 +3311,8 @@ module_optimize(Scheme_Object *data, Optimize_Info *info)
|
|||
if (!cont) {
|
||||
/* If we have new constants, re-optimize to inline: */
|
||||
if (consts) {
|
||||
int flags;
|
||||
|
||||
if (!info->top_level_consts) {
|
||||
info->top_level_consts = consts;
|
||||
} else {
|
||||
|
@ -3285,8 +3326,16 @@ module_optimize(Scheme_Object *data, Optimize_Info *info)
|
|||
}
|
||||
}
|
||||
|
||||
/* Same as in letrec: assume CLOS_SINGLE_RESULT and
|
||||
CLOS_PRESERVES_MARKS for all, but then assume not for all
|
||||
if any turn out not (i.e., approximate fix point). */
|
||||
(void)set_code_closure_flags(cl_first,
|
||||
CLOS_SINGLE_RESULT | CLOS_PRESERVES_MARKS | CLOS_RESULT_TENTATIVE,
|
||||
0xFFFF);
|
||||
|
||||
while (1) {
|
||||
/* Re-optimize this expression: */
|
||||
/* Re-optimize this expression. We can optimize anything without
|
||||
shift-cloning, since there are no local variables in scope. */
|
||||
e = scheme_optimize_expr(SCHEME_CAR(start_simltaneous_b), info);
|
||||
SCHEME_CAR(start_simltaneous_b) = e;
|
||||
|
||||
|
@ -3294,8 +3343,14 @@ module_optimize(Scheme_Object *data, Optimize_Info *info)
|
|||
break;
|
||||
start_simltaneous_b = SCHEME_CDR(start_simltaneous_b);
|
||||
}
|
||||
|
||||
flags = set_code_closure_flags(cl_first, 0, 0xFFFF);
|
||||
(void)set_code_closure_flags(cl_first,
|
||||
(flags & (CLOS_SINGLE_RESULT | CLOS_PRESERVES_MARKS)),
|
||||
~(CLOS_SINGLE_RESULT | CLOS_PRESERVES_MARKS | CLOS_RESULT_TENTATIVE));
|
||||
}
|
||||
|
||||
cl_last = cl_first = NULL;
|
||||
consts = NULL;
|
||||
start_simltaneous_b = SCHEME_CDR(b);
|
||||
}
|
||||
|
|
|
@ -2178,7 +2178,7 @@ static unsigned char *add_range(unsigned char *r, int *_j, RoomState *rs,
|
|||
return add_byte_range(lo, hi, count, r, _j, rs, did_alt, 0);
|
||||
}
|
||||
|
||||
static int translate(unsigned char *s, int len, unsigned char **result)
|
||||
static int translate(unsigned char *s, int len, char **result)
|
||||
{
|
||||
int j;
|
||||
RoomState rs;
|
||||
|
@ -2468,7 +2468,7 @@ static int translate(unsigned char *s, int len, unsigned char **result)
|
|||
}
|
||||
|
||||
r[j] = 0;
|
||||
*result = r;
|
||||
*result = (char *)r;
|
||||
return j;
|
||||
}
|
||||
|
||||
|
@ -2497,7 +2497,7 @@ static Scheme_Object *do_make_regexp(const char *who, int is_byte, int argc, Sch
|
|||
slen = SCHEME_BYTE_STRTAG_VAL(bs);
|
||||
|
||||
if (!is_byte) {
|
||||
slen = translate((unsigned char *)s, slen, (unsigned char **)&s);
|
||||
slen = translate((unsigned char *)s, slen, &s);
|
||||
#if 0
|
||||
/* Debugging, to see the translated regexp: */
|
||||
{
|
||||
|
|
167
src/mzscheme/src/schmap.inc
Normal file
167
src/mzscheme/src/schmap.inc
Normal file
|
@ -0,0 +1,167 @@
|
|||
|
||||
/* common code for `map', `for-each', `andmap' and `ormap' */
|
||||
|
||||
/*
|
||||
DO_MAP = C function name
|
||||
MAP_NAME = Scheme function name as string
|
||||
MAP_MODE => map
|
||||
FOR_EACH_MODE => for-each
|
||||
AND_MODE => and mode
|
||||
OR_MODE => or mode
|
||||
*/
|
||||
|
||||
static Scheme_Object *
|
||||
DO_MAP(int argc, Scheme_Object *argv[])
|
||||
{
|
||||
# define NUM_QUICK_ARGS 3
|
||||
# define NUM_QUICK_RES 5
|
||||
int i, size = 0, l, pos;
|
||||
Scheme_Object *quick1[NUM_QUICK_ARGS], *quick2[NUM_QUICK_ARGS];
|
||||
Scheme_Object **working, **args;
|
||||
# ifdef MAP_MODE
|
||||
Scheme_Object *quick3[NUM_QUICK_RES], **resarray;
|
||||
# endif
|
||||
# ifndef FOR_EACH_MODE
|
||||
Scheme_Object *v;
|
||||
# endif
|
||||
int cc;
|
||||
|
||||
if (!SCHEME_PROCP(argv[0]))
|
||||
scheme_wrong_type(MAP_NAME, "procedure", 0, argc, argv);
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
l = scheme_proper_list_length(argv[i]);
|
||||
|
||||
if (l < 0)
|
||||
scheme_wrong_type(MAP_NAME, "proper list", i, argc, argv);
|
||||
|
||||
if (i == 1)
|
||||
size = l;
|
||||
else if (size != l) {
|
||||
char *argstr;
|
||||
long alen;
|
||||
|
||||
argstr = scheme_make_args_string("", -1, argc, argv, &alen);
|
||||
|
||||
scheme_raise_exn(MZEXN_FAIL_CONTRACT,
|
||||
"%s: all lists must have same size%t",
|
||||
MAP_NAME, argstr, alen);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (SCHEME_FALSEP(scheme_get_or_check_arity(argv[0], argc - 1))) {
|
||||
char *s;
|
||||
long aelen;
|
||||
|
||||
s = scheme_make_arity_expect_string(argv[0], argc - 1, NULL, &aelen);
|
||||
|
||||
scheme_raise_exn(MZEXN_FAIL_CONTRACT,
|
||||
"%s: arity mismatch for %t", MAP_NAME,
|
||||
s, aelen);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (argc <= (NUM_QUICK_ARGS + 1)) {
|
||||
args = quick1;
|
||||
working = quick2;
|
||||
} else {
|
||||
args = MALLOC_N(Scheme_Object *, argc - 1);
|
||||
working = MALLOC_N(Scheme_Object *, argc - 1);
|
||||
}
|
||||
|
||||
#ifdef MAP_MODE
|
||||
if (size <= NUM_QUICK_RES)
|
||||
resarray = quick3;
|
||||
else
|
||||
resarray = MALLOC_N(Scheme_Object *, size);
|
||||
#endif
|
||||
|
||||
/* Copy argc into working array */
|
||||
for (i = 1; i < argc; i++) {
|
||||
working[i-1] = argv[i];
|
||||
}
|
||||
|
||||
--argc;
|
||||
|
||||
pos = 0;
|
||||
while (pos < size) {
|
||||
/* collect args to apply */
|
||||
for (i = 0; i < argc ; i++) {
|
||||
if (!SCHEME_PAIRP(working[i])) {
|
||||
/* There was a mutation! */
|
||||
scheme_raise_exn(MZEXN_FAIL_CONTRACT,
|
||||
"%s: argument list mutated",
|
||||
MAP_NAME);
|
||||
return NULL;
|
||||
}
|
||||
args[i] = SCHEME_CAR(working[i]);
|
||||
working[i] = SCHEME_CDR(working[i]);
|
||||
}
|
||||
|
||||
cc = scheme_cont_capture_count;
|
||||
|
||||
#ifdef MAP_MODE
|
||||
v = _scheme_apply(argv[0], argc, args);
|
||||
#else
|
||||
# ifdef FOR_EACH_MODE
|
||||
if (pos + 1 == size) {
|
||||
return _scheme_tail_apply(argv[0], argc, args);
|
||||
} else {
|
||||
_scheme_apply_multi(argv[0], argc, args);
|
||||
}
|
||||
# else
|
||||
if (pos + 1 == size) {
|
||||
return _scheme_tail_apply(argv[0], argc, args);
|
||||
} else {
|
||||
v = _scheme_apply(argv[0], argc, args);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
if (cc != scheme_cont_capture_count) {
|
||||
/* Copy arrays to avoid messing with other continuations */
|
||||
#ifdef MAP_MODE
|
||||
if (size > NUM_QUICK_RES) {
|
||||
Scheme_Object **naya;
|
||||
naya = MALLOC_N(Scheme_Object *, size);
|
||||
memcpy(naya, resarray, pos * sizeof(Scheme_Object *));
|
||||
resarray = naya;
|
||||
}
|
||||
#endif
|
||||
if ((argc > NUM_QUICK_ARGS) && (pos + 1 < size)) {
|
||||
Scheme_Object **naya;
|
||||
args = MALLOC_N(Scheme_Object *, argc);
|
||||
naya = MALLOC_N(Scheme_Object *, argc);
|
||||
memcpy(naya, working, argc * sizeof(Scheme_Object *));
|
||||
working = naya;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAP_MODE
|
||||
resarray[pos] = v;
|
||||
#endif
|
||||
#ifdef AND_MODE
|
||||
if (SCHEME_FALSEP(v))
|
||||
return scheme_false;
|
||||
#endif
|
||||
#ifdef OR_MODE
|
||||
if (SCHEME_TRUEP(v))
|
||||
return v;
|
||||
#endif
|
||||
pos++;
|
||||
}
|
||||
|
||||
#ifdef MAP_MODE
|
||||
return scheme_build_list(size, resarray);
|
||||
#endif
|
||||
#ifdef FOR_EACH_MODE
|
||||
return scheme_void;
|
||||
#endif
|
||||
#ifdef AND_MODE
|
||||
return scheme_true;
|
||||
#endif
|
||||
#ifdef OR_MODE
|
||||
return scheme_false;
|
||||
#endif
|
||||
}
|
|
@ -217,6 +217,7 @@ void scheme_do_add_global_symbol(Scheme_Env *env, Scheme_Object *sym,
|
|||
|
||||
extern Scheme_Object *scheme_values_func;
|
||||
extern Scheme_Object *scheme_void_proc;
|
||||
extern Scheme_Object *scheme_call_with_values_proc;
|
||||
|
||||
extern Scheme_Object *scheme_define_values_syntax, *scheme_define_syntaxes_syntax;
|
||||
extern Scheme_Object *scheme_lambda_syntax;
|
||||
|
@ -1505,9 +1506,11 @@ typedef struct Scheme_Comp_Env
|
|||
|
||||
#define CLOS_HAS_REST 1
|
||||
#define CLOS_HAS_REF_ARGS 2
|
||||
#define CLOS_ONLY_LOCALS 4
|
||||
#define CLOS_PRESERVES_MARKS 4
|
||||
#define CLOS_FOLDABLE 8
|
||||
#define CLOS_IS_METHOD 16
|
||||
#define CLOS_SINGLE_RESULT 32
|
||||
#define CLOS_RESULT_TENTATIVE 64
|
||||
|
||||
typedef struct Scheme_Compile_Expand_Info
|
||||
{
|
||||
|
@ -1574,6 +1577,9 @@ typedef struct Optimize_Info
|
|||
char letrec_not_twice, enforce_const;
|
||||
Scheme_Hash_Table *top_level_consts;
|
||||
|
||||
/* Set by expression optimization: */
|
||||
int single_result, preserves_marks; /* negative means "tentative", due to fixpoint in progress */
|
||||
|
||||
char **stat_dists; /* (pos, depth) => used? */
|
||||
int *sd_depths;
|
||||
int used_toplevel;
|
||||
|
@ -1581,7 +1587,7 @@ typedef struct Optimize_Info
|
|||
} Optimize_Info;
|
||||
|
||||
typedef struct Scheme_Object *(*Scheme_Syntax_Optimizer)(Scheme_Object *data, Optimize_Info *info);
|
||||
typedef struct Scheme_Object *(*Scheme_Syntax_Cloner)(Scheme_Object *data, Optimize_Info *info, int delta, int closure_depth);
|
||||
typedef struct Scheme_Object *(*Scheme_Syntax_Cloner)(int dup_ok, Scheme_Object *data, Optimize_Info *info, int delta, int closure_depth);
|
||||
typedef struct Scheme_Object *(*Scheme_Syntax_Shifter)(Scheme_Object *data, int delta, int after_depth);
|
||||
|
||||
typedef struct CPort Mz_CPort;
|
||||
|
@ -1629,7 +1635,7 @@ typedef struct {
|
|||
#define ZERO_SIZED_CLOSUREP(closure) !(closure->code->closure_size)
|
||||
|
||||
typedef struct Scheme_Native_Closure_Data {
|
||||
MZTAG_IF_REQUIRED
|
||||
Scheme_Inclhash_Object iso; /* type tag only set when needed, but flags always needed */
|
||||
Scheme_Closed_Prim *code;
|
||||
union {
|
||||
void *tail_code; /* For non-case-lambda */
|
||||
|
@ -1757,7 +1763,8 @@ int scheme_is_sub_env(Scheme_Comp_Env *stx_env, Scheme_Comp_Env *env);
|
|||
#define REQUIRE_EXPD 8
|
||||
#define DEFINE_FOR_SYNTAX_EXPD 9
|
||||
#define REF_EXPD 10
|
||||
#define _COUNT_EXPD_ 11
|
||||
#define APPVALS_EXPD 11
|
||||
#define _COUNT_EXPD_ 12
|
||||
|
||||
#define scheme_register_syntax(i, fo, fr, fv, fe, fj, cl, sh, pa) \
|
||||
(scheme_syntax_optimizers[i] = fo, \
|
||||
|
@ -1783,10 +1790,13 @@ Scheme_Object *scheme_make_syntax_resolved(int idx, Scheme_Object *data);
|
|||
Scheme_Object *scheme_make_syntax_compiled(int idx, Scheme_Object *data);
|
||||
|
||||
Scheme_Object *scheme_optimize_expr(Scheme_Object *, Optimize_Info *);
|
||||
Scheme_Object *scheme_optimize_list(Scheme_Object *, Optimize_Info *);
|
||||
Scheme_Object *scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline);
|
||||
Scheme_Object *scheme_optimize_lets_for_test(Scheme_Object *form, Optimize_Info *info);
|
||||
|
||||
Scheme_Object *scheme_optimize_apply_values(Scheme_Object *f, Scheme_Object *e,
|
||||
Optimize_Info *info,
|
||||
int e_single_result);
|
||||
|
||||
int scheme_compiled_duplicate_ok(Scheme_Object *o);
|
||||
int scheme_compiled_propagate_ok(Scheme_Object *o, Optimize_Info *info);
|
||||
|
||||
|
@ -1820,9 +1830,9 @@ void scheme_optimize_mutated(Optimize_Info *info, int pos);
|
|||
Scheme_Object *scheme_optimize_reverse(Optimize_Info *info, int pos, int unless_mutated);
|
||||
int scheme_optimize_is_used(Optimize_Info *info, int pos);
|
||||
|
||||
Scheme_Object *scheme_optimize_clone(Scheme_Object *obj, Optimize_Info *info, int delta, int closure_depth);
|
||||
Scheme_Object *scheme_optimize_clone(int dup_ok, Scheme_Object *obj, Optimize_Info *info, int delta, int closure_depth);
|
||||
Scheme_Object *scheme_optimize_shift(Scheme_Object *obj, int delta, int after_depth);
|
||||
Scheme_Object *scheme_clone_closure_compilation(Scheme_Object *obj, Optimize_Info *info, int delta, int closure_depth);
|
||||
Scheme_Object *scheme_clone_closure_compilation(int dup_ok, Scheme_Object *obj, Optimize_Info *info, int delta, int closure_depth);
|
||||
Scheme_Object *scheme_shift_closure_compilation(Scheme_Object *obj, int delta, int after_depth);
|
||||
|
||||
int scheme_closure_body_size(Scheme_Closure_Data *closure_data, int check_assign);
|
||||
|
@ -2512,6 +2522,10 @@ void scheme_count_generic(Scheme_Object *o, long *s, long *e, Scheme_Hash_Table
|
|||
|
||||
Scheme_Object *scheme_checked_car(int argc, Scheme_Object **argv);
|
||||
Scheme_Object *scheme_checked_cdr(int argc, Scheme_Object **argv);
|
||||
Scheme_Object *scheme_checked_caar(int argc, Scheme_Object **argv);
|
||||
Scheme_Object *scheme_checked_cadr(int argc, Scheme_Object **argv);
|
||||
Scheme_Object *scheme_checked_cdar(int argc, Scheme_Object **argv);
|
||||
Scheme_Object *scheme_checked_cddr(int argc, Scheme_Object **argv);
|
||||
Scheme_Object *scheme_checked_vector_ref(int argc, Scheme_Object **argv);
|
||||
Scheme_Object *scheme_checked_vector_set(int argc, Scheme_Object **argv);
|
||||
Scheme_Object *scheme_checked_string_ref(int argc, Scheme_Object *argv[]);
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
|
||||
#define MZSCHEME_VERSION_MAJOR 352
|
||||
#define MZSCHEME_VERSION_MINOR 4
|
||||
#define MZSCHEME_VERSION_MINOR 5
|
||||
|
||||
#define MZSCHEME_VERSION "352.4" _MZ_SPECIAL_TAG
|
||||
#define MZSCHEME_VERSION "352.5" _MZ_SPECIAL_TAG
|
||||
|
|
|
@ -357,9 +357,9 @@ static void uncopy_stack(int ok, Scheme_Jumpup_Buf *b, long *prev)
|
|||
|
||||
if (c->cont) {
|
||||
#ifdef STACK_GROWS_UP
|
||||
top_delta = ((unsigned long)c->stack_from
|
||||
- ((unsigned long)c->cont->buf.stack_from
|
||||
+ c->cont->buf.stack_size));
|
||||
top_delta = (((unsigned long)c->cont->buf.stack_from
|
||||
+ c->cont->buf.stack_size)
|
||||
- (unsigned long)c->stack_from);
|
||||
#else
|
||||
bottom_delta = ((unsigned long)c->stack_from
|
||||
+ c->stack_size
|
||||
|
|
|
@ -2554,8 +2554,7 @@
|
|||
"((_() expr1 expr ...)(syntax/loc stx(let() expr1 expr ...)))"
|
||||
"((_((pred handler) ...) expr1 expr ...)"
|
||||
"(quasisyntax/loc stx"
|
||||
"(let((l(list(cons pred handler) ...))"
|
||||
"(body(lambda() expr1 expr ...)))"
|
||||
"(let((l(list(cons pred handler) ...)))"
|
||||
"(let((bpz(continuation-mark-set-first #f break-enabled-key)))"
|
||||
"(with-continuation-mark"
|
||||
" break-enabled-key"
|
||||
|
@ -2589,7 +2588,7 @@
|
|||
"((cdar l) e)))))"
|
||||
"(else"
|
||||
"(loop(cdr l))))))))))"
|
||||
"(call-with-values body"
|
||||
"(call-with-values(lambda() expr1 expr ...)"
|
||||
"(lambda args(lambda()(apply values args)))))))))))))))))))"
|
||||
"(values(wh #t)(wh #f))))"
|
||||
"(define-syntax set!-values"
|
||||
|
|
|
@ -2943,8 +2943,7 @@
|
|||
[(_ () expr1 expr ...) (syntax/loc stx (let () expr1 expr ...))]
|
||||
[(_ ([pred handler] ...) expr1 expr ...)
|
||||
(quasisyntax/loc stx
|
||||
(let ([l (list (cons pred handler) ...)]
|
||||
[body (lambda () expr1 expr ...)])
|
||||
(let ([l (list (cons pred handler) ...)])
|
||||
;; Capture current break parameterization, so we can use it to
|
||||
;; evaluate the body
|
||||
(let ([bpz (continuation-mark-set-first #f break-enabled-key)])
|
||||
|
@ -2988,7 +2987,7 @@
|
|||
((cdar l) e))))]
|
||||
[else
|
||||
(loop (cdr l))])))))])
|
||||
(call-with-values body
|
||||
(call-with-values (lambda () expr1 expr ...)
|
||||
(lambda args (lambda () (apply values args)))))))))))))])))])
|
||||
(values (wh #t) (wh #f))))
|
||||
|
||||
|
|
|
@ -97,6 +97,7 @@ static Scheme_Object *define_syntaxes_execute(Scheme_Object *expr);
|
|||
static Scheme_Object *define_for_syntaxes_execute(Scheme_Object *expr);
|
||||
static Scheme_Object *case_lambda_execute(Scheme_Object *expr);
|
||||
static Scheme_Object *begin0_execute(Scheme_Object *data);
|
||||
static Scheme_Object *apply_values_execute(Scheme_Object *data);
|
||||
|
||||
static Scheme_Object *bangboxenv_execute(Scheme_Object *data);
|
||||
static Scheme_Object *bangboxvalue_execute(Scheme_Object *data);
|
||||
|
@ -108,14 +109,17 @@ static Scheme_Object *define_syntaxes_optimize(Scheme_Object *expr, Optimize_Inf
|
|||
static Scheme_Object *define_for_syntaxes_optimize(Scheme_Object *expr, Optimize_Info *info);
|
||||
static Scheme_Object *case_lambda_optimize(Scheme_Object *expr, Optimize_Info *info);
|
||||
static Scheme_Object *begin0_optimize(Scheme_Object *data, Optimize_Info *info);
|
||||
static Scheme_Object *apply_values_optimize(Scheme_Object *data, Optimize_Info *info);
|
||||
|
||||
static Scheme_Object *begin0_clone(Scheme_Object *data, Optimize_Info *info, int delta, int closure_depth);
|
||||
static Scheme_Object *set_clone(Scheme_Object *data, Optimize_Info *info, int delta, int closure_depth);
|
||||
static Scheme_Object *begin0_clone(int dup_ok, Scheme_Object *data, Optimize_Info *info, int delta, int closure_depth);
|
||||
static Scheme_Object *set_clone(int dup_ok, Scheme_Object *data, Optimize_Info *info, int delta, int closure_depth);
|
||||
static Scheme_Object *apply_values_clone(int dup_ok, Scheme_Object *data, Optimize_Info *info, int delta, int closure_depth);
|
||||
|
||||
static Scheme_Object *begin0_shift(Scheme_Object *data, int delta, int after_depth);
|
||||
static Scheme_Object *set_shift(Scheme_Object *data, int delta, int after_depth);
|
||||
static Scheme_Object *ref_shift(Scheme_Object *data, int delta, int after_depth);
|
||||
static Scheme_Object *case_lambda_shift(Scheme_Object *data, int delta, int after_depth);
|
||||
static Scheme_Object *apply_values_shift(Scheme_Object *data, int delta, int after_depth);
|
||||
|
||||
static Scheme_Object *define_values_resolve(Scheme_Object *data, Resolve_Info *info);
|
||||
static Scheme_Object *ref_resolve(Scheme_Object *data, Resolve_Info *info);
|
||||
|
@ -124,6 +128,7 @@ static Scheme_Object *define_syntaxes_resolve(Scheme_Object *expr, Resolve_Info
|
|||
static Scheme_Object *define_for_syntaxes_resolve(Scheme_Object *expr, Resolve_Info *info);
|
||||
static Scheme_Object *case_lambda_resolve(Scheme_Object *expr, Resolve_Info *info);
|
||||
static Scheme_Object *begin0_resolve(Scheme_Object *data, Resolve_Info *info);
|
||||
static Scheme_Object *apply_values_resolve(Scheme_Object *data, Resolve_Info *info);
|
||||
|
||||
static void define_values_validate(Scheme_Object *data, Mz_CPort *port,
|
||||
char *stack, Scheme_Hash_Table *ht, Scheme_Object **tls,
|
||||
|
@ -153,6 +158,10 @@ static void begin0_validate(Scheme_Object *data, Mz_CPort *port,
|
|||
char *stack, Scheme_Hash_Table *ht, Scheme_Object **tls,
|
||||
int depth, int letlimit, int delta,
|
||||
int num_toplevels, int num_stxes, int num_lifts);
|
||||
static void apply_values_validate(Scheme_Object *data, Mz_CPort *port,
|
||||
char *stack, Scheme_Hash_Table *ht, Scheme_Object **tls,
|
||||
int depth, int letlimit, int delta,
|
||||
int num_toplevels, int num_stxes, int num_lifts);
|
||||
static void bangboxenv_validate(Scheme_Object *data, Mz_CPort *port,
|
||||
char *stack, Scheme_Hash_Table *ht, Scheme_Object **tls,
|
||||
int depth, int letlimit, int delta,
|
||||
|
@ -169,6 +178,7 @@ static Scheme_Object *define_syntaxes_jit(Scheme_Object *expr);
|
|||
static Scheme_Object *define_for_syntaxes_jit(Scheme_Object *expr);
|
||||
static Scheme_Object *case_lambda_jit(Scheme_Object *expr);
|
||||
static Scheme_Object *begin0_jit(Scheme_Object *data);
|
||||
static Scheme_Object *apply_values_jit(Scheme_Object *data);
|
||||
static Scheme_Object *bangboxvalue_jit(Scheme_Object *data);
|
||||
|
||||
static Scheme_Object *expand_lam(int argc, Scheme_Object **argv);
|
||||
|
@ -277,6 +287,12 @@ scheme_init_syntax (Scheme_Env *env)
|
|||
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_execute, apply_values_jit,
|
||||
apply_values_clone, apply_values_shift, 1);
|
||||
|
||||
scheme_register_syntax(BOXENV_EXPD,
|
||||
NULL, NULL, bangboxenv_validate,
|
||||
bangboxenv_execute, NULL,
|
||||
|
@ -1378,6 +1394,9 @@ set_optimize(Scheme_Object *data, Optimize_Info *info)
|
|||
|
||||
val = scheme_optimize_expr(val, info);
|
||||
|
||||
info->preserves_marks = 1;
|
||||
info->single_result = 1;
|
||||
|
||||
if (SAME_TYPE(SCHEME_TYPE(var), scheme_local_type)) {
|
||||
int pos, delta;
|
||||
|
||||
|
@ -1398,7 +1417,7 @@ set_optimize(Scheme_Object *data, Optimize_Info *info)
|
|||
}
|
||||
|
||||
static Scheme_Object *
|
||||
set_clone(Scheme_Object *data, Optimize_Info *info, int delta, int closure_depth)
|
||||
set_clone(int dup_ok, Scheme_Object *data, Optimize_Info *info, int delta, int closure_depth)
|
||||
{
|
||||
Scheme_Object *var, *val, *set_undef;
|
||||
|
||||
|
@ -1407,10 +1426,10 @@ set_clone(Scheme_Object *data, Optimize_Info *info, int delta, int closure_depth
|
|||
var = SCHEME_CAR(data);
|
||||
val = SCHEME_CDR(data);
|
||||
|
||||
val = scheme_optimize_clone(val, info, delta, closure_depth);
|
||||
val = scheme_optimize_clone(dup_ok, val, info, delta, closure_depth);
|
||||
if (!val) return NULL;
|
||||
if (SAME_TYPE(SCHEME_TYPE(var), scheme_local_type)) {
|
||||
var = scheme_optimize_clone(var, info, delta, closure_depth);
|
||||
var = scheme_optimize_clone(dup_ok, var, info, delta, closure_depth);
|
||||
if (!var) return NULL;
|
||||
}
|
||||
|
||||
|
@ -1650,7 +1669,7 @@ set_expand(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Expand_Info *erec,
|
|||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/* #%variable-reference */
|
||||
/* #%variable-reference */
|
||||
/**********************************************************************/
|
||||
|
||||
static Scheme_Object *
|
||||
|
@ -1685,8 +1704,11 @@ static void ref_validate(Scheme_Object *tl, Mz_CPort *port,
|
|||
}
|
||||
|
||||
static Scheme_Object *
|
||||
ref_optimize(Scheme_Object *tl, Optimize_Info *rslv)
|
||||
ref_optimize(Scheme_Object *tl, Optimize_Info *info)
|
||||
{
|
||||
info->preserves_marks = 1;
|
||||
info->single_result = 1;
|
||||
|
||||
return scheme_make_syntax_compiled(REF_EXPD, tl);
|
||||
}
|
||||
|
||||
|
@ -1782,6 +1804,134 @@ ref_expand(Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Expand_Info *erec,
|
|||
return form;
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/* apply-values */
|
||||
/**********************************************************************/
|
||||
|
||||
static Scheme_Object *apply_values_execute(Scheme_Object *data)
|
||||
{
|
||||
Scheme_Object *f, *v;
|
||||
|
||||
f = SCHEME_CAR(data);
|
||||
|
||||
f = _scheme_eval_linked_expr_multi(f);
|
||||
if (!SCHEME_PROCP(f)) {
|
||||
Scheme_Object *a[1];
|
||||
a[0] = f;
|
||||
scheme_wrong_type("call-with-values", "procedure", -1, 1, a);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
v = _scheme_eval_linked_expr_multi(SCHEME_CDR(data));
|
||||
if (SAME_OBJ(v, SCHEME_MULTIPLE_VALUES)) {
|
||||
Scheme_Thread *p = scheme_current_thread;
|
||||
int num_rands = p->ku.multiple.count;
|
||||
|
||||
if (num_rands > p->tail_buffer_size) {
|
||||
/* scheme_tail_apply will allocate */
|
||||
if (SAME_OBJ(p->ku.multiple.array, p->values_buffer))
|
||||
p->values_buffer = NULL;
|
||||
}
|
||||
return scheme_tail_apply(f, num_rands, p->ku.multiple.array);
|
||||
} else {
|
||||
Scheme_Object *a[1];
|
||||
a[0] = v;
|
||||
return scheme_tail_apply(f, 1, a);
|
||||
}
|
||||
}
|
||||
|
||||
static Scheme_Object *apply_values_jit(Scheme_Object *data)
|
||||
{
|
||||
Scheme_Object *f, *e;
|
||||
|
||||
f = scheme_jit_expr(SCHEME_CAR(data));
|
||||
e = scheme_jit_expr(SCHEME_CDR(data));
|
||||
|
||||
if (SAME_OBJ(f, SCHEME_CAR(data))
|
||||
&& SAME_OBJ(e, SCHEME_CAR(data)))
|
||||
return data;
|
||||
else
|
||||
return scheme_make_pair(f, e);
|
||||
}
|
||||
|
||||
static Scheme_Object *
|
||||
apply_values_optimize(Scheme_Object *data, Optimize_Info *info)
|
||||
{
|
||||
Scheme_Object *f, *e;
|
||||
|
||||
f = SCHEME_CAR(data);
|
||||
e = SCHEME_CDR(data);
|
||||
|
||||
f = scheme_optimize_expr(f, info);
|
||||
e = scheme_optimize_expr(e, info);
|
||||
|
||||
return scheme_optimize_apply_values(f, e, info, info->single_result);
|
||||
}
|
||||
|
||||
static Scheme_Object *
|
||||
apply_values_resolve(Scheme_Object *data, Resolve_Info *rslv)
|
||||
{
|
||||
Scheme_Object *f, *e;
|
||||
|
||||
f = SCHEME_CAR(data);
|
||||
e = SCHEME_CDR(data);
|
||||
|
||||
f = scheme_resolve_expr(f, rslv);
|
||||
e = scheme_resolve_expr(e, rslv);
|
||||
|
||||
return scheme_make_syntax_resolved(APPVALS_EXPD, cons(f, e));
|
||||
}
|
||||
|
||||
static Scheme_Object *
|
||||
apply_values_shift(Scheme_Object *data, int delta, int after_depth)
|
||||
{
|
||||
Scheme_Object *e;
|
||||
|
||||
e = scheme_optimize_shift(SCHEME_CAR(data), delta, after_depth);
|
||||
SCHEME_CAR(data) = e;
|
||||
|
||||
e = scheme_optimize_shift(SCHEME_CDR(data), delta, after_depth);
|
||||
SCHEME_CAR(data) = e;
|
||||
|
||||
return scheme_make_syntax_compiled(APPVALS_EXPD, data);
|
||||
}
|
||||
|
||||
static Scheme_Object *
|
||||
apply_values_clone(int dup_ok, Scheme_Object *data, Optimize_Info *info, int delta, int closure_depth)
|
||||
{
|
||||
Scheme_Object *f, *e;
|
||||
|
||||
f = SCHEME_CAR(data);
|
||||
e = SCHEME_CDR(data);
|
||||
|
||||
f = scheme_optimize_clone(dup_ok, f, info, delta, closure_depth);
|
||||
if (!f) return NULL;
|
||||
e = scheme_optimize_clone(dup_ok, e, info, delta, closure_depth);
|
||||
if (!e) return NULL;
|
||||
|
||||
return scheme_make_syntax_compiled(APPVALS_EXPD, cons(f, e));
|
||||
}
|
||||
|
||||
static void apply_values_validate(Scheme_Object *data, Mz_CPort *port,
|
||||
char *stack, Scheme_Hash_Table *ht, Scheme_Object **tls,
|
||||
int depth, int letlimit, int delta,
|
||||
int num_toplevels, int num_stxes, int num_lifts)
|
||||
{
|
||||
Scheme_Object *f, *e;
|
||||
|
||||
f = SCHEME_CAR(data);
|
||||
e = SCHEME_CDR(data);
|
||||
|
||||
scheme_validate_expr(port, f, stack, ht, tls,
|
||||
depth, letlimit, delta,
|
||||
num_toplevels, num_stxes, num_lifts,
|
||||
NULL, 0);
|
||||
scheme_validate_expr(port, e, stack, ht, tls,
|
||||
depth, letlimit, delta,
|
||||
num_toplevels, num_stxes, num_lifts,
|
||||
NULL, 0);
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/* case-lambda */
|
||||
/**********************************************************************/
|
||||
|
@ -1976,6 +2126,9 @@ case_lambda_optimize(Scheme_Object *expr, Optimize_Info *info)
|
|||
seq->array[i] = le;
|
||||
}
|
||||
|
||||
info->preserves_marks = 1;
|
||||
info->single_result = 1;
|
||||
|
||||
return scheme_make_syntax_compiled(CASE_LAMBDA_EXPD, expr);
|
||||
}
|
||||
|
||||
|
@ -2421,6 +2574,71 @@ int scheme_compiled_propagate_ok(Scheme_Object *value, Optimize_Info *info)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static Scheme_Object *make_clones(Scheme_Compiled_Let_Value *retry_start,
|
||||
Scheme_Compiled_Let_Value *pre_body,
|
||||
Optimize_Info *body_info)
|
||||
{
|
||||
Scheme_Compiled_Let_Value *clv;
|
||||
Scheme_Object *value, *clone, *pr;
|
||||
Scheme_Object *last = NULL, *first = NULL;
|
||||
|
||||
clv = retry_start;
|
||||
while (1) {
|
||||
value = clv->value;
|
||||
if (SAME_TYPE(SCHEME_TYPE(value), scheme_compiled_unclosed_procedure_type)) {
|
||||
clone = scheme_optimize_clone(1, value, body_info, 0, 0);
|
||||
if (clone) {
|
||||
pr = scheme_make_raw_pair(scheme_make_raw_pair(value, clone), NULL);
|
||||
if (last)
|
||||
SCHEME_CDR(last) = pr;
|
||||
else
|
||||
first = pr;
|
||||
last = pr;
|
||||
}
|
||||
}
|
||||
if (clv == pre_body)
|
||||
break;
|
||||
clv = (Scheme_Compiled_Let_Value *)clv->body;
|
||||
}
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
static int set_code_flags(Scheme_Compiled_Let_Value *retry_start,
|
||||
Scheme_Compiled_Let_Value *pre_body,
|
||||
Scheme_Object *clones,
|
||||
int set_flags, int mask_flags)
|
||||
{
|
||||
Scheme_Compiled_Let_Value *clv;
|
||||
Scheme_Object *value, *first;
|
||||
int flags = CLOS_SINGLE_RESULT | CLOS_PRESERVES_MARKS;
|
||||
|
||||
/* The first in a clone pair is the one that is consulted for
|
||||
references. The second one is the clone, and its the one whose
|
||||
flags are updated by optimization. So consult the clone, and set
|
||||
flags in both. */
|
||||
|
||||
clv = retry_start;
|
||||
while (clones) {
|
||||
value = retry_start->value;
|
||||
first = SCHEME_CAR(clones);
|
||||
if (SAME_OBJ(value, SCHEME_CAR(first))) {
|
||||
Scheme_Closure_Data *data;
|
||||
data = (Scheme_Closure_Data *)SCHEME_CDR(first);
|
||||
flags = (flags & SCHEME_CLOSURE_DATA_FLAGS(data));
|
||||
SCHEME_CLOSURE_DATA_FLAGS(data) = set_flags | (SCHEME_CLOSURE_DATA_FLAGS(data) & mask_flags);
|
||||
data = (Scheme_Closure_Data *)SCHEME_CAR(first);
|
||||
SCHEME_CLOSURE_DATA_FLAGS(data) = set_flags | (SCHEME_CLOSURE_DATA_FLAGS(data) & mask_flags);
|
||||
clones = SCHEME_CDR(clones);
|
||||
}
|
||||
if (clv == pre_body)
|
||||
break;
|
||||
clv = (Scheme_Compiled_Let_Value *)clv->body;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
Scheme_Object *
|
||||
scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline)
|
||||
{
|
||||
|
@ -2448,6 +2666,8 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline)
|
|||
} else {
|
||||
info = scheme_optimize_info_add_frame(info, 1, 0, 0);
|
||||
body = scheme_optimize_expr(clv->value, info);
|
||||
info->next->single_result = info->single_result;
|
||||
info->next->preserves_marks = info->preserves_marks;
|
||||
scheme_optimize_info_done(info);
|
||||
return body;
|
||||
}
|
||||
|
@ -2510,7 +2730,7 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline)
|
|||
if ((vpos < head->count) && (vpos >= pos))
|
||||
value = NULL;
|
||||
else {
|
||||
/* Convert value back to a pre-optimized local coordinate.
|
||||
/* Convert value back to a pre-optimized local coordinates.
|
||||
This must be done with respect to body_info, not
|
||||
rhs_info, because we attach the value to body_info: */
|
||||
value = scheme_optimize_reverse(body_info, vpos, 1);
|
||||
|
@ -2531,37 +2751,59 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline)
|
|||
&& !is_liftable(((Scheme_Compiled_Let_Value *)pre_body->body)->value, head->count, 5)))) {
|
||||
if (did_set_value) {
|
||||
/* Next RHS ends a reorderable sequence.
|
||||
Re-optimize from retry_start to pre_body, inclusive. */
|
||||
Re-optimize from retry_start to pre_body, inclusive.
|
||||
For procedures, assume CLOS_SINGLE_RESULT and CLOS_PRESERVES_MARKS for all,
|
||||
but then assume not for all if any turn out not (i.e., approximate fix point). */
|
||||
int flags;
|
||||
Scheme_Object *clones, *cl, *cl_first;
|
||||
/* Set-flags loop: */
|
||||
clones = make_clones(retry_start, pre_body, body_info);
|
||||
(void)set_code_flags(retry_start, pre_body, clones,
|
||||
CLOS_SINGLE_RESULT | CLOS_PRESERVES_MARKS | CLOS_RESULT_TENTATIVE,
|
||||
0xFFFF);
|
||||
/* Re-optimize loop: */
|
||||
clv = retry_start;
|
||||
cl = clones;
|
||||
while (1) {
|
||||
value = retry_start->value;
|
||||
if (SAME_TYPE(SCHEME_TYPE(value), scheme_compiled_unclosed_procedure_type)) {
|
||||
value = clv->value;
|
||||
if (cl)
|
||||
cl_first = SCHEME_CAR(cl);
|
||||
else
|
||||
cl_first = NULL;
|
||||
if (cl_first && SAME_OBJ(value, SCHEME_CAR(cl_first))) {
|
||||
/* Try optimization. */
|
||||
Scheme_Object *self_value;
|
||||
self_value = scheme_optimize_clone(value, body_info, 0, 0);
|
||||
if (self_value) {
|
||||
/* Try optimization. */
|
||||
int sz;
|
||||
int sz;
|
||||
|
||||
/* Drop old size, and remove old inline fuel: */
|
||||
sz = scheme_closure_body_size((Scheme_Closure_Data *)value, 0);
|
||||
body_info->size -= (sz + 1);
|
||||
cl = SCHEME_CDR(cl);
|
||||
self_value = SCHEME_CDR(cl_first);
|
||||
|
||||
/* Setting letrec_not_twice prevents inlinining
|
||||
of letrec bindings in this RHS. There's a small
|
||||
chance that we miss some optimizations, but we
|
||||
avoid the possibility of N^2 behavior. */
|
||||
body_info->letrec_not_twice = 1;
|
||||
|
||||
value = scheme_optimize_expr(self_value, body_info);
|
||||
|
||||
body_info->letrec_not_twice = 0;
|
||||
|
||||
retry_start->value = value;
|
||||
}
|
||||
/* Drop old size, and remove old inline fuel: */
|
||||
sz = scheme_closure_body_size((Scheme_Closure_Data *)value, 0);
|
||||
body_info->size -= (sz + 1);
|
||||
|
||||
/* Setting letrec_not_twice prevents inlinining
|
||||
of letrec bindings in this RHS. There's a small
|
||||
chance that we miss some optimizations, but we
|
||||
avoid the possibility of N^2 behavior. */
|
||||
body_info->letrec_not_twice = 1;
|
||||
|
||||
value = scheme_optimize_expr(self_value, body_info);
|
||||
|
||||
body_info->letrec_not_twice = 0;
|
||||
|
||||
clv->value = value;
|
||||
}
|
||||
if (retry_start == pre_body)
|
||||
if (clv == pre_body)
|
||||
break;
|
||||
retry_start = (Scheme_Compiled_Let_Value *)retry_start->body;
|
||||
clv = (Scheme_Compiled_Let_Value *)clv->body;
|
||||
}
|
||||
/* Check flags loop: */
|
||||
flags = set_code_flags(retry_start, pre_body, clones, 0, 0xFFFF);
|
||||
/* Reset-flags loop: */
|
||||
(void)set_code_flags(retry_start, pre_body, clones,
|
||||
(flags & (CLOS_SINGLE_RESULT | CLOS_PRESERVES_MARKS)),
|
||||
~(CLOS_SINGLE_RESULT | CLOS_PRESERVES_MARKS | CLOS_RESULT_TENTATIVE));
|
||||
}
|
||||
retry_start = NULL;
|
||||
did_set_value = 0;
|
||||
|
@ -2580,6 +2822,9 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline)
|
|||
pre_body->body = body;
|
||||
info->size += 1;
|
||||
|
||||
info->single_result = body_info->single_result;
|
||||
info->preserves_marks = body_info->preserves_marks;
|
||||
|
||||
/* Clear used flags where possible */
|
||||
if (all_simple) {
|
||||
body = head->body;
|
||||
|
@ -2637,6 +2882,9 @@ scheme_optimize_lets_for_test(Scheme_Object *form, Optimize_Info *info)
|
|||
|
||||
form = scheme_optimize_expr((Scheme_Object *)b3, sub_info);
|
||||
|
||||
info->single_result = sub_info->single_result;
|
||||
info->preserves_marks = sub_info->preserves_marks;
|
||||
|
||||
scheme_optimize_info_done(sub_info);
|
||||
|
||||
return form;
|
||||
|
@ -3720,15 +3968,15 @@ Scheme_Object *scheme_compiled_void()
|
|||
static Scheme_Object *
|
||||
begin0_execute(Scheme_Object *obj)
|
||||
{
|
||||
Scheme_Thread *p = scheme_current_thread;
|
||||
Scheme_Object *v, **mv;
|
||||
int i, mc, apos;
|
||||
|
||||
i = ((Scheme_Sequence *)obj)->count;
|
||||
|
||||
v = _scheme_eval_linked_expr_multi_wp(((Scheme_Sequence *)obj)->array[0], p);
|
||||
v = _scheme_eval_linked_expr_multi(((Scheme_Sequence *)obj)->array[0]);
|
||||
i--;
|
||||
if (SAME_OBJ(v, SCHEME_MULTIPLE_VALUES)) {
|
||||
Scheme_Thread *p = scheme_current_thread;
|
||||
mv = p->ku.multiple.array;
|
||||
mc = p->ku.multiple.count;
|
||||
if (SAME_OBJ(mv, p->values_buffer))
|
||||
|
@ -3740,10 +3988,11 @@ begin0_execute(Scheme_Object *obj)
|
|||
|
||||
apos = 1;
|
||||
while (i--) {
|
||||
(void)_scheme_eval_linked_expr_multi_wp(((Scheme_Sequence *)obj)->array[apos++], p);
|
||||
(void)_scheme_eval_linked_expr_multi(((Scheme_Sequence *)obj)->array[apos++]);
|
||||
}
|
||||
|
||||
if (mv) {
|
||||
Scheme_Thread *p = scheme_current_thread;
|
||||
p->ku.multiple.array = mv;
|
||||
p->ku.multiple.count = mc;
|
||||
}
|
||||
|
@ -3815,13 +4064,16 @@ begin0_optimize(Scheme_Object *obj, Optimize_Info *info)
|
|||
((Scheme_Sequence *)obj)->array[i] = le;
|
||||
}
|
||||
|
||||
/* Optimization of expression 0 has already set single_result */
|
||||
info->preserves_marks = 1;
|
||||
|
||||
return scheme_make_syntax_compiled(BEGIN0_EXPD, obj);
|
||||
}
|
||||
|
||||
static Scheme_Object *
|
||||
begin0_clone(Scheme_Object *obj, Optimize_Info *info, int delta, int closure_depth)
|
||||
begin0_clone(int dup_ok, Scheme_Object *obj, Optimize_Info *info, int delta, int closure_depth)
|
||||
{
|
||||
obj = scheme_optimize_clone(obj, info, delta, closure_depth);
|
||||
obj = scheme_optimize_clone(dup_ok, obj, info, delta, closure_depth);
|
||||
if (!obj) return NULL;
|
||||
return scheme_make_syntax_compiled(BEGIN0_EXPD, obj);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user