# New Ticket Created by  Matt Fowles 
# Please include the string:  [perl #24848]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=24848 >


All~

This patch sets up a generic register stack (using macro's for values 
that change) that the real register stacks can then implement.  This was 
discussed on list several months ago, but nobody ever got around to it.  
So I did ;-)

I am not entirely certain how to fix the manifest, but I did try...  
Other than that all tests pass for make test and make testj.  make testP 
still has one failing test (timer 3) but that failed before.

Hopefully this will reduce code duplication a little :-)

Sorry for got the attachment...

Matt

Index: MANIFEST
===================================================================
RCS file: /cvs/public/parrot/MANIFEST,v
retrieving revision 1.528
diff -u -r1.528 MANIFEST
--- MANIFEST    7 Jan 2004 15:22:35 -0000       1.528
+++ MANIFEST    8 Jan 2004 08:21:40 -0000
@@ -2231,6 +2231,7 @@
 src/exec_start.c                                  []
 src/exit.c                                        []
 src/extend.c                                     []
+src/generic_register.c                            []
 src/global_setup.c                                []
 src/hash.c                                        []
 src/headers.c                                     []
Index: src/register.c
===================================================================
RCS file: /cvs/public/parrot/src/register.c,v
retrieving revision 1.34
diff -u -r1.34 register.c
--- src/register.c      28 Oct 2003 03:13:06 -0000      1.34
+++ src/register.c      8 Jan 2004 08:21:47 -0000
@@ -12,305 +12,51 @@
 
 #include "parrot/parrot.h"
 
-/*=for api register Parrot_push_i
-  pushes a new integer register frame onto the corresponding frame stack
-*/
-void
-Parrot_push_i(struct Parrot_Interp *interpreter, void *where)
-{
-    /* Do we have any space in the current savestack? If so, memcpy
-     * down */
-    if (interpreter->ctx.int_reg_top->used < FRAMES_PER_CHUNK) {
-        memcpy(&interpreter->ctx.int_reg_top->
-               IRegFrame[interpreter->ctx.int_reg_top->used],
-               where, sizeof(struct IRegFrame));
-        interpreter->ctx.int_reg_top->used++;
-    }
-    /* Nope, so either move to next stack chunk or grow the stack */
-    else {
-        struct IRegChunk *next_chunk;
-        if (interpreter->ctx.int_reg_top->next)
-            next_chunk = interpreter->ctx.int_reg_top->next;
-        else {
-            next_chunk = mem_sys_allocate(sizeof(struct IRegChunk));
-            next_chunk->next = NULL;
-            next_chunk->prev = interpreter->ctx.int_reg_top;
-            interpreter->ctx.int_reg_top->next = next_chunk;
-        }
-        next_chunk->used = 1;
-        interpreter->ctx.int_reg_top = next_chunk;
-        memcpy(&next_chunk->IRegFrame[0],
-               where, sizeof(struct IRegFrame));
-    }
-}
 
-/*=for api register Parrot_pop_i
-  pops an integer register frame from the corresponding frame stack
-*/
-void
-Parrot_pop_i(struct Parrot_Interp *interpreter, void *where)
-{
-    struct IRegChunk *top = interpreter->ctx.int_reg_top;
-    /* Do we even have anything? */
-    if (top->used > 0) {
-        top->used--;
-        memcpy(where,
-               &top->IRegFrame[top->used], sizeof(struct IRegFrame));
-        /* Empty? */
-        if (!top->used) {
-            /* Yep, drop down a frame. Maybe */
-            if (top->prev) {
-                /* Keep one stack segment spare to avoid thrashing */
-                if (top->next) {
-                    mem_sys_free(top->next);
-                    top->next = NULL;
-                }
-                interpreter->ctx.int_reg_top = top->prev;
-            }
-        }
-    }
-    /* Nope. So pitch a fit */
-    else {
-        internal_exception(NO_REG_FRAMES, "No more I register frames to pop!");
-    }
-}
+#define REG_PUSH Parrot_push_i
+#define REG_POP Parrot_pop_i
+#define REG_CLEAR Parrot_clear_i
+#define REG_TOP int_reg_top
+#define REG_NAME int_reg
+#define REG_CHUNK IRegChunk
+#define REG_FRAME IRegFrame
+#define REG_EXCEPTION_STRING "No more I register frames to pop!"
+#define REG_NULL 0
+#include "generic_register.c"
+
+#define REG_PUSH Parrot_push_s
+#define REG_POP Parrot_pop_s
+#define REG_CLEAR Parrot_clear_s
+#define REG_TOP string_reg_top
+#define REG_NAME string_reg
+#define REG_CHUNK SRegChunk
+#define REG_FRAME SRegFrame
+#define REG_EXCEPTION_STRING "No more S register frames to pop!"
+#define REG_NULL NULL
+#include "generic_register.c"
+
+#define REG_PUSH Parrot_push_n
+#define REG_POP Parrot_pop_n
+#define REG_CLEAR Parrot_clear_n
+#define REG_TOP num_reg_top
+#define REG_NAME num_reg
+#define REG_CHUNK NRegChunk
+#define REG_FRAME NRegFrame
+#define REG_EXCEPTION_STRING "No more N register frames to pop!"
+#define REG_NULL 0
+#include "generic_register.c"
+
+#define REG_PUSH Parrot_push_p
+#define REG_POP Parrot_pop_p
+#define REG_CLEAR Parrot_clear_p
+#define REG_TOP pmc_reg_top
+#define REG_NAME pmc_reg
+#define REG_CHUNK PRegChunk
+#define REG_FRAME PRegFrame
+#define REG_EXCEPTION_STRING "No more P register frames to pop!"
+#define REG_NULL PMCNULL
+#include "generic_register.c"
 
-/*=for api register Parrot_clear_i
-  sets each integer register in the current set to 0
-*/
-void
-Parrot_clear_i(struct Parrot_Interp *interpreter)
-{
-    int i;
-    for (i = 0; i < NUM_REGISTERS; i++) {
-        interpreter->int_reg.registers[i] = 0;
-    }
-}
-
-/*=for api register Parrot_push_s
-  pushes a new string register frame onto the corresponding frame stack
-*/
-void
-Parrot_push_s(struct Parrot_Interp *interpreter, void *where)
-{
-    /* Do we have any space in the current savestack? If so, memcpy
-     * down */
-    if (interpreter->ctx.string_reg_top->used < FRAMES_PER_CHUNK) {
-        memcpy(&interpreter->ctx.string_reg_top->
-               SRegFrame[interpreter->ctx.string_reg_top->used],
-               where, sizeof(struct SRegFrame));
-        interpreter->ctx.string_reg_top->used++;
-    }
-    /* Nope, so either move to next stack chunk or grow the stack */
-    else {
-        struct SRegChunk *next_chunk;
-        if (interpreter->ctx.string_reg_top->next)
-            next_chunk = interpreter->ctx.string_reg_top->next;
-        else {
-            next_chunk = mem_sys_allocate(sizeof(struct SRegChunk));
-            next_chunk->next = NULL;
-            next_chunk->prev = interpreter->ctx.string_reg_top;
-            interpreter->ctx.string_reg_top->next = next_chunk;
-        }
-        next_chunk->used = 1;
-        interpreter->ctx.string_reg_top = next_chunk;
-        memcpy(&next_chunk->SRegFrame[0],
-               where, sizeof(struct SRegFrame));
-    }
-}
-
-/*=for api register Parrot_pop_s
-  pops a string register frame from the corresponding frame stack
-*/
-void
-Parrot_pop_s(struct Parrot_Interp *interpreter, void *where)
-{
-    struct SRegChunk *top = interpreter->ctx.string_reg_top;
-    /* Do we even have anything? */
-    if (top->used > 0) {
-        top->used--;
-        memcpy(where,
-               &top->SRegFrame[top->used], sizeof(struct SRegFrame));
-        /* Empty? */
-        if (!top->used) {
-            /* Yep, drop down a frame. Maybe */
-            if (top->prev) {
-                /* Keep one stack segment spare to avoid thrashing */
-                if (top->next) {
-                    mem_sys_free(top->next);
-                    top->next = NULL;
-                }
-                interpreter->ctx.string_reg_top = top->prev;
-            }
-        }
-    }
-    /* Nope. So pitch a fit */
-    else {
-        internal_exception(NO_REG_FRAMES, "No more S register frames to pop!");
-    }
-}
-
-/*=for api register Parrot_clear_s
-  sets each string register in the current set to NULL
-*/
-void
-Parrot_clear_s(struct Parrot_Interp *interpreter)
-{
-    int i;
-    for (i = 0; i < NUM_REGISTERS; i++) {
-        interpreter->string_reg.registers[i] = NULL;
-    }
-}
-
-/*=for api register Parrot_push_n
-  pushes a new numeric register frame onto the corresponding frame stack
-*/
-void
-Parrot_push_n(struct Parrot_Interp *interpreter, void *where)
-{
-    /* Do we have any space in the current savestack? If so, memcpy
-     * down */
-    if (interpreter->ctx.num_reg_top->used < FRAMES_PER_CHUNK) {
-        memcpy(&interpreter->ctx.num_reg_top->
-               NRegFrame[interpreter->ctx.num_reg_top->used],
-               where, sizeof(struct NRegFrame));
-        interpreter->ctx.num_reg_top->used++;
-    }
-    /* Nope, so either move to next stack chunk or grow the stack */
-    else {
-        struct NRegChunk *next_chunk;
-        if (interpreter->ctx.num_reg_top->next)
-            next_chunk = interpreter->ctx.num_reg_top->next;
-        else {
-            next_chunk = mem_sys_allocate(sizeof(struct NRegChunk));
-            next_chunk->next = NULL;
-            next_chunk->prev = interpreter->ctx.num_reg_top;
-            interpreter->ctx.num_reg_top->next = next_chunk;
-        }
-        next_chunk->used = 1;
-        interpreter->ctx.num_reg_top = next_chunk;
-        memcpy(&next_chunk->NRegFrame[0],
-               where, sizeof(struct NRegFrame));
-    }
-}
-
-/*=for api register Parrot_pop_n
-  pops a numeric register frame from the corresponding frame stack
-*/
-void
-Parrot_pop_n(struct Parrot_Interp *interpreter, void *where)
-{
-    struct NRegChunk *top = interpreter->ctx.num_reg_top;
-    /* Do we even have anything? */
-    if (top->used > 0) {
-        top->used--;
-        memcpy(where,
-               &top->NRegFrame[top->used], sizeof(struct NRegFrame));
-        /* Empty? */
-        if (!top->used) {
-            /* Yep, drop down a frame. Maybe */
-            if (top->prev) {
-                /* Keep one stack segment spare to avoid thrashing */
-                if (top->next) {
-                    mem_sys_free(top->next);
-                    top->next = NULL;
-                }
-                interpreter->ctx.num_reg_top = top->prev;
-            }
-        }
-    }
-    /* Nope. So pitch a fit */
-    else {
-        internal_exception(NO_REG_FRAMES, "No more N register frames to pop!");
-    }
-}
-
-/*=for api register Parrot_clear_n
-  sets each numeric register in the current set to 0.0
-*/
-void
-Parrot_clear_n(struct Parrot_Interp *interpreter)
-{
-    int i;
-    for (i = 0; i < NUM_REGISTERS; i++) {
-        interpreter->num_reg.registers[i] = 0.0;
-    }
-}
-
-/*=for api register Parrot_push_p
-  pushes a new PMC register frame onto the corresponding frame stack
-*/
-void
-Parrot_push_p(struct Parrot_Interp *interpreter, void *where)
-{
-    /* Do we have any space in the current savestack? If so, memcpy
-     * down */
-    if (interpreter->ctx.pmc_reg_top->used < FRAMES_PER_CHUNK) {
-        memcpy(&interpreter->ctx.pmc_reg_top->
-               PRegFrame[interpreter->ctx.pmc_reg_top->used],
-               where, sizeof(struct PRegFrame));
-        interpreter->ctx.pmc_reg_top->used++;
-    }
-    /* Nope, so either move to next stack chunk or grow the stack */
-    else {
-        struct PRegChunk *next_chunk;
-        if (interpreter->ctx.pmc_reg_top->next)
-            next_chunk = interpreter->ctx.pmc_reg_top->next;
-        else {
-            next_chunk = mem_sys_allocate(sizeof(struct PRegChunk));
-            next_chunk->next = NULL;
-            next_chunk->prev = interpreter->ctx.pmc_reg_top;
-            interpreter->ctx.pmc_reg_top->next = next_chunk;
-        }
-        next_chunk->used = 1;
-        interpreter->ctx.pmc_reg_top = next_chunk;
-        memcpy(&next_chunk->PRegFrame[0],
-               where, sizeof(struct PRegFrame));
-    }
-}
-
-/*=for api register Parrot_pop_p
-  pops a PMC register frame from the corresponding frame stack
-*/
-void
-Parrot_pop_p(struct Parrot_Interp *interpreter, void *where)
-{
-    struct PRegChunk *top = interpreter->ctx.pmc_reg_top;
-    /* Do we even have anything? */
-    if (top->used > 0) {
-        top->used--;
-        memcpy(where,
-               &top->PRegFrame[top->used], sizeof(struct PRegFrame));
-        /* Empty? */
-        if (!top->used) {
-            /* Yep, drop down a frame. Maybe */
-            if (top->prev) {
-                /* Keep one stack segment spare to avoid thrashing */
-                if (top->next) {
-                    mem_sys_free(top->next);
-                    top->next = NULL;
-                }
-                interpreter->ctx.pmc_reg_top = top->prev;
-            }
-        }
-    }
-    /* Nope. So pitch a fit */
-    else {
-        internal_exception(NO_REG_FRAMES, "No more P register frames to pop!");
-    }
-}
-
-/*=for api register Parrot_clear_p
-  sets each pmc register in the current set to NULL
-*/
-void
-Parrot_clear_p(struct Parrot_Interp *interpreter)
-{
-    int i;
-    for (i = 0; i < NUM_REGISTERS; i++) {
-        interpreter->pmc_reg.registers[i] = PMCNULL;
-    }
-}
 
 /*=for api register Parrot_push_on_stack
    pushes something on the parrot stack
--- /dev/null   2003-12-20 00:23:52.000000000 -0500
+++ src/generic_register.c      2004-01-08 00:41:09.000000000 -0500
@@ -0,0 +1,109 @@
+/* generic_register.c
+ *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
+ *  CVS Info
+ *     $Id: generic_register.c,v 1.00 2004/1/08 03:13:06 mrjoltcola Exp $
+ *  Overview:
+ *     This is the generic version of all of the register handling routines
+ *     one uses the #defines to instantiate specific versions of the register
+ *     stacks, as follows
+ *
+ *     #define REG_PUSH Parrot_push_p
+ *     #define REG_POP Parrot_pop_p
+ *     #define REG_CLEAR Parrot_clear_p
+ *     #define REG_TOP pmc_reg_top
+ *     #define REG_NAME pmc_reg
+ *     #define REG_CHUNK PRegChunk
+ *     #define REG_FRAME PRegFrame
+ *     #define REG_EXCEPTION_STRING "No more P register frames to pop!"
+ *     #define REG_NULL PMCNULL
+ *     #include "generic_register.c"
+ *
+ *     This file will undef all of there defines on at the end of file.
+ *  Data Structure and Algorithms:
+ *  History:
+ *  Notes:
+ *  References:
+ *     the original version of this was taken from register.c which now just
+ *     #includes this file several times with different #defines...
+ */
+
+#include "parrot/parrot.h"
+
+/*=for api register Parrot_push_i
+  pushes a new integer register frame onto the corresponding frame stack
+*/
+void
+REG_PUSH(struct Parrot_Interp *interpreter, void *where)
+{
+    /* Do we have any space in the current savestack? If so, memcpy
+     * down */
+    if (interpreter->ctx.REG_TOP->used < FRAMES_PER_CHUNK) {
+        memcpy(&interpreter->ctx.REG_TOP->
+               REG_FRAME[interpreter->ctx.REG_TOP->used],
+               where, sizeof(struct REG_FRAME));
+        interpreter->ctx.REG_TOP->used++;
+    }
+    /* Nope, so either move to next stack chunk or grow the stack */
+    else {
+        struct REG_CHUNK *next_chunk;
+        if (interpreter->ctx.REG_TOP->next)
+            next_chunk = interpreter->ctx.REG_TOP->next;
+        else {
+            next_chunk = mem_sys_allocate(sizeof(struct REG_CHUNK));
+            next_chunk->next = NULL;
+            next_chunk->prev = interpreter->ctx.REG_TOP;
+            interpreter->ctx.REG_TOP->next = next_chunk;
+        }
+        next_chunk->used = 1;
+        interpreter->ctx.REG_TOP = next_chunk;
+        memcpy(&next_chunk->REG_FRAME[0],
+               where, sizeof(struct REG_FRAME));
+    }
+}
+
+/*=for api register Parrot_pop_i
+  pops an integer register frame from the corresponding frame stack
+*/
+void
+REG_POP(struct Parrot_Interp *interpreter, void *where)
+{
+    struct REG_CHUNK *top = interpreter->ctx.REG_TOP;
+    /* Do we even have anything? */
+    if (top->used > 0) {
+        top->used--;
+        memcpy(where,
+               &top->REG_FRAME[top->used], sizeof(struct REG_FRAME));
+        /* Empty? */
+        if (!top->used) {
+            /* Yep, drop down a frame. Maybe */
+            if (top->prev) {
+                /* Keep one stack segment spare to avoid thrashing */
+                if (top->next) {
+                    mem_sys_free(top->next);
+                    top->next = NULL;
+                }
+                interpreter->ctx.REG_TOP = top->prev;
+            }
+        }
+    }
+    /* Nope. So pitch a fit */
+    else {
+        internal_exception(NO_REG_FRAMES, REG_EXCEPTION_STRING);
+    }
+}
+
+/*=for api register Parrot_clear_i
+  sets each integer register in the current set to 0
+*/
+void
+REG_CLEAR(struct Parrot_Interp *interpreter)
+{
+    int i;
+    for (i = 0; i < NUM_REGISTERS; i++) {
+        interpreter->REG_NAME.registers[i] = REG_NULL;
+    }
+}
+
+#undef REG_PUSH
+#undef REG_POP
+#undef REG_CLEAR
+#undef REG_TOP
+#undef REG_NAME
+#undef REG_CHUNK
+#undef REG_FRAME
+#undef REG_EXCEPTION_STRING
+#undef REG_NULL
+/*
+ * Local variables:
+ * c-indentation-style: bsd
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vim: expandtab shiftwidth=4:
+*/

Reply via email to