cvsuser 04/10/28 09:19:48
Modified: src inter_run.c
Log:
runops - handle overflow
Revision Changes Path
1.15 +64 -16 parrot/src/inter_run.c
Index: inter_run.c
===================================================================
RCS file: /cvs/public/parrot/src/inter_run.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- inter_run.c 28 Oct 2004 12:13:31 -0000 1.14
+++ inter_run.c 28 Oct 2004 16:19:47 -0000 1.15
@@ -1,6 +1,6 @@
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-$Id: inter_run.c,v 1.14 2004/10/28 12:13:31 leo Exp $
+$Id: inter_run.c,v 1.15 2004/10/28 16:19:47 leo Exp $
=head1 NAME
@@ -197,12 +197,17 @@
{
opcode_t offset, *dest;
struct parrot_regs_t *bp;
- int next[4];
+ int next[4], count[4];
int i;
PMC *ret_c;
+ const char *p;
+ PMC *p3 = PMCNULL;
+ int clear_p3, need_p3, max;
- for (i = 0; i < 4; i++)
+ for (i = 0; i < 4; i++) {
next[i] = 5;
+ count[i] = 0;
+ }
ret_c = new_ret_continuation_pmc(interpreter, NULL);
dest = VTABLE_invoke(interpreter, sub, NULL);
@@ -210,13 +215,44 @@
interpreter->ctx.current_cont = REG_PMC(1) = ret_c;
interpreter->ctx.current_object = REG_PMC(2) = obj;
REG_STR(0) = meth;
+
+ /*
+ * count arguments, check for overflow
+ */
+ for (p = sig + 1; *p; ++p) {
+ switch (*p) {
+ case 'v': break;
+ case 'I': ++count[0]; break;
+ case 'S': ++count[1]; break;
+ case 'P': ++count[2]; break;
+ case 'N': ++count[3]; break;
+ }
+ }
REG_INT(0) = 1; /* kind of a prototyped call */
- REG_INT(1) = 0; /* # of I params */
- REG_INT(2) = 0; /* # of S params */
- REG_INT(3) = 0; /* # of P params */
- REG_INT(4) = 0; /* # of N params */
+ clear_p3 = need_p3 = max = 0;
+ for (i = 0; i < 4; ++i) {
+ if (count[i] < 11)
+ REG_INT(i+1) = count[i]; /* # of I params */
+ else if (count[i] == 11) {
+ REG_INT(i+1) = 11;
+ clear_p3 |= 1;
+ }
+ else {
+ REG_INT(i+1) = 11;
+ need_p3 |= 1;
+ if (count[i] > max)
+ max = count[i];
+ }
+ }
+ if (need_p3) {
+ p3 = pmc_new(interpreter, enum_class_Array);
+ VTABLE_set_integer_native(interpreter, p3, max - 11);
+ REG_PMC(3) = p3;
+ }
+ else if (clear_p3)
+ REG_PMC(3) = p3;
- while (*++sig) {
+ for (i = 0; *++sig; ) {
/*
* TODO handle overflow: if any next[] reaches 16 create
* overflow array in P3 and pass additional args in the
@@ -226,20 +262,32 @@
case 'v': /* void func, no params */
break;
case 'I': /* REG_INT */
- REG_INT(next[0]++) = va_arg(ap, INTVAL);
- ++REG_INT(1);
+ if (next[0] == 16)
+ VTABLE_set_integer_keyed_int(interpreter,
+ p3, i++, va_arg(ap, INTVAL));
+ else
+ REG_INT(next[0]++) = va_arg(ap, INTVAL);
break;
case 'S': /* REG_STR */
- REG_STR(next[1]++) = va_arg(ap, STRING*);
- ++REG_INT(2);
+ if (next[1] == 16)
+ VTABLE_set_string_keyed_int(interpreter,
+ p3, i++, va_arg(ap, STRING*));
+ else
+ REG_STR(next[1]++) = va_arg(ap, STRING*);
break;
case 'P': /* REG_PMC */
- REG_PMC(next[2]++) = va_arg(ap, PMC*);
- ++REG_INT(3);
+ if (next[2] == 16)
+ VTABLE_set_pmc_keyed_int(interpreter,
+ p3, i++, va_arg(ap, PMC*));
+ else
+ REG_PMC(next[2]++) = va_arg(ap, PMC*);
break;
case 'N': /* REG_NUM */
- REG_NUM(next[3]++) = va_arg(ap, FLOATVAL);
- ++REG_INT(4);
+ if (next[3] == 16)
+ VTABLE_set_number_keyed_int(interpreter,
+ p3, i++, va_arg(ap, FLOATVAL));
+ else
+ REG_NUM(next[3]++) = va_arg(ap, FLOATVAL);
break;
default:
internal_exception(1,