mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-06 15:40:29 +02:00
add special case for (apply values ...)
* libguile/vm-engine.c (vm_run): Move nvalues to the top level, to avoid (spurious, it seems) gcc warnings about it being used uninitialized. * libguile/vm-i-system.c (halt, return/values): Adapt to gcc silliness. Deindent some of return/values. (return/values*): New instruction, does what (apply values . args) would do. * module/language/scheme/translate.scm (custom-transformer-table): Move the apply and @apply cases here from inline.scm, because we need some more cleverness when dealing with cases like (apply values . args). (lookup-apply-transformer): Define an eval transformer for `values', turning it into ghil-values*. * module/system/il/compile.scm (codegen): Compile <ghil-values*> into return/values*. * module/system/il/ghil.scm: Add <ghil-values*> and accessors. (ghil-lookup): Add optional argument, define?, which if false tells us not to actually cache the binding if it is not found in the toplevel. * module/system/il/inline.scm: Remove apply clauses. * module/system/vm/frame.scm (bootstrap-frame?): Update heuristic for bootstrap-frame?, as the bootstrap frame is now 5 bytes since it accepts multiple values.
This commit is contained in:
parent
a222b0fa91
commit
ef24c01bff
7 changed files with 115 additions and 57 deletions
|
@ -65,6 +65,7 @@ vm_run (SCM vm, SCM program, SCM args)
|
|||
|
||||
/* Internal variables */
|
||||
int nargs = 0;
|
||||
int nvalues = 0;
|
||||
long start_time = scm_c_get_internal_run_time ();
|
||||
// SCM dynwinds = SCM_EOL;
|
||||
SCM err_msg;
|
||||
|
|
|
@ -55,7 +55,6 @@ VM_DEFINE_INSTRUCTION (nop, "nop", 0, 0, 0)
|
|||
VM_DEFINE_INSTRUCTION (halt, "halt", 0, 0, 0)
|
||||
{
|
||||
SCM ret;
|
||||
int nvalues;
|
||||
vp->time += scm_c_get_internal_run_time () - start_time;
|
||||
HALT_HOOK ();
|
||||
nvalues = SCM_I_INUM (*sp--);
|
||||
|
@ -859,55 +858,57 @@ VM_DEFINE_INSTRUCTION (return, "return", 0, 0, 1)
|
|||
|
||||
VM_DEFINE_INSTRUCTION (return_values, "return/values", 1, -1, -1)
|
||||
{
|
||||
/* nvalues declared at top level, because for some reason gcc seems to think
|
||||
that perhaps it might be used without declaration. Fooey to that, I say. */
|
||||
SCM *data;
|
||||
|
||||
nvalues = FETCH ();
|
||||
vm_return_values:
|
||||
EXIT_HOOK ();
|
||||
RETURN_HOOK ();
|
||||
{
|
||||
int nvalues = FETCH ();
|
||||
SCM *data = SCM_FRAME_DATA_ADDRESS (fp);
|
||||
|
||||
data = SCM_FRAME_DATA_ADDRESS (fp);
|
||||
#ifdef THE_GOVERNMENT_IS_AFTER_ME
|
||||
if (stack_base != data + 4)
|
||||
abort ();
|
||||
if (stack_base != data + 4)
|
||||
abort ();
|
||||
#endif
|
||||
|
||||
/* data[3] is the mv return address */
|
||||
if (nvalues != 1 && data[3])
|
||||
{
|
||||
int i;
|
||||
/* Restore registers */
|
||||
sp = SCM_FRAME_LOWER_ADDRESS (fp) - 1;
|
||||
ip = SCM_FRAME_BYTE_CAST (data[3]); /* multiple value ra */
|
||||
fp = SCM_FRAME_STACK_CAST (data[2]);
|
||||
/* data[3] is the mv return address */
|
||||
if (nvalues != 1 && data[3])
|
||||
{
|
||||
int i;
|
||||
/* Restore registers */
|
||||
sp = SCM_FRAME_LOWER_ADDRESS (fp) - 1;
|
||||
ip = SCM_FRAME_BYTE_CAST (data[3]); /* multiple value ra */
|
||||
fp = SCM_FRAME_STACK_CAST (data[2]);
|
||||
|
||||
/* Push return values, and the number of values */
|
||||
for (i = 0; i < nvalues; i++)
|
||||
*++sp = stack_base[1+i];
|
||||
*++sp = SCM_I_MAKINUM (nvalues);
|
||||
/* Push return values, and the number of values */
|
||||
for (i = 0; i < nvalues; i++)
|
||||
*++sp = stack_base[1+i];
|
||||
*++sp = SCM_I_MAKINUM (nvalues);
|
||||
|
||||
/* Finally set new stack_base */
|
||||
stack_base = SCM_FRAME_UPPER_ADDRESS (fp) - 1;
|
||||
}
|
||||
else if (nvalues >= 1)
|
||||
{
|
||||
/* Multiple values for a single-valued continuation -- here's where I
|
||||
break with guile tradition and try and do something sensible. (Also,
|
||||
this block handles the single-valued return to an mv
|
||||
continuation.) */
|
||||
/* Restore registers */
|
||||
sp = SCM_FRAME_LOWER_ADDRESS (fp) - 1;
|
||||
ip = SCM_FRAME_BYTE_CAST (data[4]); /* single value ra */
|
||||
fp = SCM_FRAME_STACK_CAST (data[2]);
|
||||
/* Finally set new stack_base */
|
||||
stack_base = SCM_FRAME_UPPER_ADDRESS (fp) - 1;
|
||||
}
|
||||
else if (nvalues >= 1)
|
||||
{
|
||||
/* Multiple values for a single-valued continuation -- here's where I
|
||||
break with guile tradition and try and do something sensible. (Also,
|
||||
this block handles the single-valued return to an mv
|
||||
continuation.) */
|
||||
/* Restore registers */
|
||||
sp = SCM_FRAME_LOWER_ADDRESS (fp) - 1;
|
||||
ip = SCM_FRAME_BYTE_CAST (data[4]); /* single value ra */
|
||||
fp = SCM_FRAME_STACK_CAST (data[2]);
|
||||
|
||||
/* Push first value */
|
||||
*++sp = stack_base[1];
|
||||
/* Push first value */
|
||||
*++sp = stack_base[1];
|
||||
|
||||
/* Finally set new stack_base */
|
||||
stack_base = SCM_FRAME_UPPER_ADDRESS (fp) - 1;
|
||||
}
|
||||
else
|
||||
goto vm_error_no_values;
|
||||
|
||||
|
||||
}
|
||||
/* Finally set new stack_base */
|
||||
stack_base = SCM_FRAME_UPPER_ADDRESS (fp) - 1;
|
||||
}
|
||||
else
|
||||
goto vm_error_no_values;
|
||||
|
||||
/* Restore the last program */
|
||||
program = SCM_FRAME_PROGRAM (fp);
|
||||
|
@ -917,6 +918,28 @@ VM_DEFINE_INSTRUCTION (return_values, "return/values", 1, -1, -1)
|
|||
NEXT;
|
||||
}
|
||||
|
||||
VM_DEFINE_INSTRUCTION (return_values_star, "return/values*", 1, -1, -1)
|
||||
{
|
||||
SCM l;
|
||||
|
||||
nvalues = FETCH ();
|
||||
#ifdef THE_GOVERNMENT_IS_AFTER_ME
|
||||
if (nvalues < 1)
|
||||
abort ();
|
||||
#endif
|
||||
|
||||
nvalues--;
|
||||
POP (l);
|
||||
while (SCM_CONSP (l))
|
||||
{
|
||||
PUSH (SCM_CAR (l));
|
||||
l = SCM_CDR (l);
|
||||
nvalues++;
|
||||
}
|
||||
|
||||
goto vm_return_values;
|
||||
}
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-file-style: "gnu"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue