All --

I've updated the simplified DO_OP patch to work with the latest out
of CVS.


Regards,

-- Gregor
 _____________________________________________________________________ 
/     perl -e 'srand(-2091643526); print chr rand 90 for (0..4)'      \

   Gregor N. Purdy                          [EMAIL PROTECTED]
   Focus Research, Inc.                http://www.focusresearch.com/
   8080 Beckett Center Drive #203                   513-860-3570 vox
   West Chester, OH 45069                           513-860-3579 fax
\_____________________________________________________________________/
? doop.patch
? t/inc.pasm
? t/jumpoob.pasm
? t/jumpsub.pasm
? t/substr.pasm
? t/jump2.pasm
? t/jump3.pasm
? t/jump4.pasm
? t/runoob.pasm
Index: .cvsignore
===================================================================
RCS file: /home/perlcvs/parrot/.cvsignore,v
retrieving revision 1.4
diff -a -u -r1.4 .cvsignore
--- .cvsignore  2001/09/19 16:48:28     1.4
+++ .cvsignore  2001/10/03 12:24:52
@@ -1,5 +1,8 @@
 basic_opcodes.c
-test_prog
-pdump
+interp_guts.c
 Makefile
+op_info.c
 Parrot/
+pdisasm
+pdump
+test_prog
Index: MANIFEST
===================================================================
RCS file: /home/perlcvs/parrot/MANIFEST,v
retrieving revision 1.23
diff -a -u -r1.23 MANIFEST
--- MANIFEST    2001/09/30 20:25:22     1.23
+++ MANIFEST    2001/10/03 12:24:52
@@ -53,6 +53,7 @@
 opcode_table
 packfile.c
 parrot.c
+pdisasm.c
 pdump.c
 process_opfunc.pl
 register.c
Index: Makefile.in
===================================================================
RCS file: /home/perlcvs/parrot/Makefile.in,v
retrieving revision 1.15
diff -a -u -r1.15 Makefile.in
--- Makefile.in 2001/10/01 22:00:23     1.15
+++ Makefile.in 2001/10/03 12:24:52
@@ -18,24 +18,28 @@
 PERL = ${perl}
 TEST_PROG = test_prog${exe}
 PDUMP = pdump${exe}
+PDISASM = pdisasm${exe}
 
 .c$(O):
        $(CC) $(CFLAGS) -o $@ -c $<
 
-all : $(TEST_PROG) $(PDUMP)
+all : $(TEST_PROG) $(PDUMP) $(PDISASM)
 
 #XXX This target is not portable to Win32
 shared: libparrot.so
 libparrot.so: $(O_FILES)
        $(CC) -shared $(C_LIBS) -o $@ $(O_FILES)
 
-$(TEST_PROG): test_main$(O) $(O_FILES)
-       $(CC) $(CFLAGS) -o $(TEST_PROG) $(O_FILES) test_main$(O) $(C_LIBS)
+$(TEST_PROG): test_main$(O) $(O_FILES) interp_guts$(O) op_info$(O)
+       $(CC) $(CFLAGS) -o $(TEST_PROG) $(O_FILES) interp_guts$(O) op_info$(O) 
+test_main$(O) $(C_LIBS)
 
-$(PDUMP): pdump$(O) $(O_FILES)
-       $(CC) $(CFLAGS) -o $(PDUMP) $(O_FILES) pdump$(O) $(C_LIBS)
+$(PDISASM): pdisasm$(O) op_info$(O) packfile$(O) memory$(O) global_setup$(O) 
+string$(O) strnative$(O)
+       $(CC) $(CFLAGS) -o $(PDISASM) pdisasm$(O) op_info$(O) packfile$(O) memory$(O) 
+global_setup$(O) string$(O) strnative$(O) $(C_LIBS)
+       
+$(PDUMP): pdump$(O) packfile$(O) memory$(O) global_setup$(O) string$(O) strnative$(O)
+       $(CC) $(CFLAGS) -o $(PDUMP) pdump$(O) packfile$(O) memory$(O) global_setup$(O) 
+string$(O) strnative$(O) $(C_LIBS)
 
-test_main$(O): $(H_FILES)
+test_main$(O): $(H_FILES) $(INC)/interp_guts.h
 
 global_setup$(O): $(H_FILES)
 
@@ -43,7 +47,7 @@
 
 strnative$(O): $(H_FILES)
 
-$(INC)/interp_guts.h: opcode_table build_interp_starter.pl
+$(INC)/interp_guts.h interp_guts.c $(INC)/op_info.h op_info.c: opcode_table 
+build_interp_starter.pl
        $(PERL) build_interp_starter.pl
 
 interpreter$(O): interpreter.c $(H_FILES) $(INC)/interp_guts.h
@@ -68,7 +72,7 @@
        $(PERL) Configure.pl
 
 clean:
-       $(RM_F) *$(O) *.s basic_opcodes.c $(INC)/interp_guts.h $(INC)/op.h $(TEST_PROG)
+       $(RM_F) *$(O) *.s basic_opcodes.c interp_guts.c $(INC)/interp_guts.h 
+$(INC)/op.h op_info.c $(INC)op_info.h $(TEST_PROG) $(PDISASM) $(PDUMP)
 
 test:
        $(PERL) t/harness
Index: build_interp_starter.pl
===================================================================
RCS file: /home/perlcvs/parrot/build_interp_starter.pl,v
retrieving revision 1.12
diff -a -u -r1.12 build_interp_starter.pl
--- build_interp_starter.pl     2001/09/24 17:19:47     1.12
+++ build_interp_starter.pl     2001/10/03 12:24:52
@@ -1,10 +1,23 @@
 # !/usr/bin/perl -w
+#
+# build_interp_starter.pl
+#
+# $Id: $
+#
+
 use strict;
 use Parrot::Opcode;
+
+my %opcodes            = Parrot::Opcode::read_ops();
+my $opcode_fingerprint = Parrot::Opcode::fingerprint();
+
+open INTERP_GUTS_H, "> include/parrot/interp_guts.h" or die "Can't open 
+include/parrot/interp_guts.h, $!/$^E";
+open INTERP_GUTS_C, "> interp_guts.c" or die "Can't open interp_guts.c, $!/$^E";
 
-open INTERP, "> include/parrot/interp_guts.h" or die "Can't open 
include/parrot/interp_guts.h, $!/$^E";
+open OP_INFO_H, "> include/parrot/op_info.h" or die "Can't open 
+include/parrot/op_info.h, $!/$^E";
+open OP_INFO_C, "> op_info.c" or die "Can't open op_info.c, $!/$^E";
 
-print INTERP <<CONST;
+print INTERP_GUTS_H <<CONST;
 /*
  *
  * interp_guts.h
@@ -13,62 +26,115 @@
  *
  * Best not edit it
  */
+
+#ifndef INTERP_GUTS_H
+#define INTERP_GUTS_H
+
+#include "parrot/config.h"
+
+typedef opcode_t *(*op_func_t)(); /* NOTE: Sure wish we could put the types here... */
+typedef op_func_t op_func_table_t[2048];
+
+extern op_func_table_t builtin_op_func_table;
+
+
+/*
+ * DO_OP macro:
+ *
+ * w = code
+ * z = interpreter
+ */
+
+#define DO_OP(PC,INTERP) PC = ((INTERP->opcode_funcs)[*PC])(PC,INTERP);
+#define OPCODE_FINGERPRINT "$opcode_fingerprint"
+
+#endif /* INTERP_GUTS_H */
 
-#define BUILD_TABLE(x) do { \\
 CONST
 
-my %opcodes            = Parrot::Opcode::read_ops();
-my $opcode_fingerprint = Parrot::Opcode::fingerprint();
 
-for my $name (sort {$opcodes{$a}{CODE} <=> $opcodes{$b}{CODE}} keys %opcodes) {
-    print INTERP "\tx[$opcodes{$name}{CODE}] = $name; \\\n";
-}
-print INTERP "} while (0);\n";
+###############################################################################
 
+print OP_INFO_H <<CONST;
+/*
+ *
+ * op_info.h
+ *
+ * this file is autogenerated by build_interp_starter.pl
+ *
+ * Best not edit it
+ */
 
-#
-# BUILD_NAME_TABLE macro:
-#
+#ifndef OP_INFO_H
+#define OP_INFO_H
+
+#include "parrot/config.h"
+
+typedef struct {
+    char *    name;
+    INTVAL    nargs;
+    char      types[5];
+} op_info_t;
+
+typedef op_info_t op_info_table_t[2048];
 
-print INTERP <<CONST;
-#define BUILD_NAME_TABLE(x) do { \\
+extern op_info_table_t builtin_op_info_table;
+
+#endif /* OP_INFO_H */
+
 CONST
 
-for my $name (sort {$opcodes{$a}{CODE} <=> $opcodes{$b}{CODE}} keys %opcodes) {
-    print INTERP "\tx[$opcodes{$name}{CODE}] = \"$name\"; \\\n";
-}
-print INTERP "} while (0);\n";
+###############################################################################
 
+print INTERP_GUTS_C <<CONST;
+/*
+ * interp_guts.c
+ *
+ * this file is autogenerated by build_interp_starter.pl
+ *
+ * Best not edit it
+ */
 
-#
-# BUILD_ARG_TABLE macro:
-#
+#include "parrot/interp_guts.h"
+#include "parrot/parrot.h"
 
-print INTERP <<CONST;
-#define BUILD_ARG_TABLE(x) do { \\
+op_func_table_t builtin_op_func_table = {
+        /* TODO: (void *) casting here sucks! */
 CONST
 
 for my $name (sort {$opcodes{$a}{CODE} <=> $opcodes{$b}{CODE}} keys %opcodes) {
-    print INTERP "\tx[$opcodes{$name}{CODE}] = $opcodes{$name}{ARGS}; \\\n";
+    printf INTERP_GUTS_C "    (void *)%-12s, /* %4d */\n", $name, 
+$opcodes{$name}{CODE};
 }
-print INTERP "} while (0);\n";
+print INTERP_GUTS_C "};\n\n";
 
 
-#
-# Spit out the DO_OP function
-#
+###############################################################################
 
-print INTERP <<EOI;
+print OP_INFO_C <<CONST;
+/*
+ * op_info.c
+ *
+ * this file is autogenerated by build_interp_starter.pl
+ *
+ * Best not edit it
+ */
 
-#define DO_OP(w,x,y,z) do { \\
-    x = z->opcode_funcs; \\
-    y = x[*w]; \\
-    w = (y)(w,z); \\
- } while (0);
-EOI
+#include "parrot/op_info.h"
 
-# Spit out the OPCODE_FINGERPRINT macro
-print INTERP <<EOI
+op_info_table_t builtin_op_info_table = {
+CONST
 
-#define OPCODE_FINGERPRINT "$opcode_fingerprint"
-EOI
+for my $name (sort {$opcodes{$a}{CODE} <=> $opcodes{$b}{CODE}} keys %opcodes) {
+    printf OP_INFO_C "    { %-14s, %d, { ",
+       "\"$name\"", $opcodes{$name}{ARGS};
+
+    if ($opcodes{$name}{ARGS}) {
+       printf OP_INFO_C " %-18s }", join(", ", map { "'$_'" } 
+@{$opcodes{$name}{TYPES}});
+    } else {
+        printf OP_INFO_C " %-18s }", "'*'";
+    }
+
+    printf OP_INFO_C " }, /* %4d */\n", $opcodes{$name}{CODE};
+}
+print OP_INFO_C "};\n\n";
+
Index: interpreter.c
===================================================================
RCS file: /home/perlcvs/parrot/interpreter.c,v
retrieving revision 1.21
diff -a -u -r1.21 interpreter.c
--- interpreter.c       2001/10/02 14:01:30     1.21
+++ interpreter.c       2001/10/03 12:24:53
@@ -12,10 +12,12 @@
 
 #include "parrot/parrot.h"
 #include "parrot/interp_guts.h"
+#include "parrot/op_info.h"
 
-char *op_names[2048];
-int   op_args[2048];
 
+/* char * op_names[2048]; */
+/* op_t   op_info[2048]; */
+
 /*=for api interpreter check_fingerprint
  * TODO: Not really part of the API, but here's the docs.
  * Check the bytecode's opcode table fingerprint.
@@ -47,10 +49,6 @@
  */
 opcode_t *
 runops_notrace_core (struct Parrot_Interp *interpreter) {
-    /* Move these out of the inner loop. No need to redeclare 'em each
-       time through */
-    opcode_t *(* func)();
-    opcode_t *(**temp)();
     opcode_t * code_start;
     INTVAL         code_size;
     opcode_t * code_end;
@@ -63,7 +61,7 @@
     pc = code_start;
 
     while (pc >= code_start && pc < code_end && *pc) {
-        DO_OP(pc, temp, func, interpreter);
+        DO_OP(pc, interpreter);
     }
 
     return pc;
@@ -75,14 +73,16 @@
  * and ARGS. Used by runops_trace.
  */
 void
-trace_op(opcode_t * code_start, opcode_t * code_end, opcode_t *pc) {
+trace_op(struct Parrot_Interp * interpreter, opcode_t * code_start, opcode_t * 
+code_end, opcode_t *pc) {
     int i;
 
     if (pc >= code_start && pc < code_end) {
-        fprintf(stderr, "PC=%ld; OP=%ld (%s)", (long)(pc - code_start), *pc, 
op_names[*pc]);
-        if (op_args[*pc]) {
+        fprintf(stderr, "PC=%ld; OP=%ld (%s)", (long)(pc - code_start), *pc,
+            interpreter->opcode_info[*pc].name);
+
+        if (interpreter->opcode_info[*pc].nargs) {
             fprintf(stderr, "; ARGS=(");
-            for(i = 0; i < op_args[*pc]; i++) {
+            for(i = 0; i < interpreter->opcode_info[*pc].nargs; i++) {
                 if (i) { fprintf(stderr, ", "); }
                 fprintf(stderr, "%ld", *(pc + i + 1));
             }
@@ -101,10 +101,6 @@
  */
 opcode_t *
 runops_trace_core (struct Parrot_Interp *interpreter) {
-    /* Move these out of the inner loop. No need to redeclare 'em each
-       time through */
-    opcode_t *( *func)();
-    opcode_t *(**temp)();
     opcode_t * code_start;
     INTVAL         code_size;
     opcode_t * code_end;
@@ -116,12 +112,11 @@
 
     pc = code_start;
 
-    trace_op(code_start, code_end, pc);
-    
-    while (pc >= code_start && pc < code_end && *pc) {
-        DO_OP(pc, temp, func, interpreter);
+    trace_op(interpreter, code_start, code_end, pc);
 
-        trace_op(code_start, code_end, pc);
+    while (pc >= code_start && pc < code_end && *pc) {
+        DO_OP(pc, interpreter);
+        trace_op(interpreter, code_start, code_end, pc);
     }
 
     return pc;
@@ -233,18 +228,9 @@
     /* Need an empty stash */
     interpreter->perl_stash = mem_allocate_new_stash();
     
-    /* The default opcode function table would be a good thing here... */
-    {
-        opcode_t *(**foo)();
-        foo = mem_sys_allocate(2048 * sizeof(void *));
-        
-        BUILD_TABLE(foo);
-        
-        interpreter->opcode_funcs = (void*)foo;
-
-        BUILD_NAME_TABLE(op_names);
-        BUILD_ARG_TABLE(op_args);
-    }
+    /* Load the builtin op func and info tables */
+    interpreter->opcode_funcs = builtin_op_func_table;
+    interpreter->opcode_info  = builtin_op_info_table;
     
     /* In case the I/O system needs something */
     Init_IO(interpreter);
Index: pdisasm.c
===================================================================
RCS file: pdisasm.c
diff -N pdisasm.c
--- /dev/null   Wed Oct  3 03:04:34 2001
+++ pdisasm.c   Wed Oct  3 05:24:53 2001
@@ -0,0 +1,171 @@
+/* pdisasm.c
+ *  Copyright: (When this is determined...it will go here)
+ *  CVS Info
+ *     $Id: $
+ *  Overview:
+ *     A program to disassemble Parrot programs from Pack Files.
+ *  Data Structure and Algorithms:
+ *  History:
+ *  Notes:
+ *  References:
+ */
+
+#include "parrot/packfile.h"
+#include "parrot/interp_guts.h"
+
+
+/*
+** disassemble()
+*/
+
+
+void
+disassemble(PackFile * pf) {
+    IV     byte_code_size;
+    char * byte_code;
+    char * byte_code_end;
+    char * cursor;
+    IV *   iv_ptr;
+    NV *   nv_ptr;
+
+    byte_code_size = PackFile_get_byte_code_size(pf);
+    byte_code      = PackFile_get_byte_code(pf);
+    byte_code_end  = byte_code + byte_code_size;
+
+    cursor = byte_code;
+
+    while(cursor < byte_code_end) {
+        IV     op_code;
+        char * op_name;
+        IV     iv_arg;
+        NV     nv_arg;
+        int    i;
+      
+        iv_ptr = (IV *)cursor;
+        op_code = *iv_ptr;
+        cursor += sizeof(IV);
+
+        op_name = builtin_op_info_table[op_code].name;
+
+        printf("%08x: %-12s ", cursor - byte_code, op_name);
+
+        for (i = 0; i < builtin_op_info_table[op_code].nargs; i++) {
+            char arg_type = builtin_op_info_table[op_code].types[i];
+
+            switch (arg_type) {
+                case 'D':
+                    iv_arg = *(IV *)cursor;
+                    cursor += sizeof(IV);
+                    printf("%s%d", (i ? ", " : ""), iv_arg);
+                    break;
+
+                case 'I':
+                case 'N':
+                case 'P':
+                case 'S':
+                    iv_arg = *(IV *)cursor;
+                    cursor += sizeof(IV);
+                    printf("%s%c%d", (i ? ", " : ""), arg_type, iv_arg);
+                    break;
+
+                case 'i':
+                    iv_arg = *(IV *)cursor;
+                    cursor += sizeof(IV);
+                    printf("%s%d", (i ? ", " : ""), iv_arg);
+                    break;
+
+                case 'n':
+                    nv_arg = *(NV *)cursor;
+                    cursor += sizeof(NV);
+                    printf("%s%g", (i ? ", " : ""), nv_arg);
+                    break;
+
+                case 's':
+                    iv_arg = *(IV *)cursor;
+                    cursor += sizeof(IV);
+                    printf("%sSTRING(%d)", (i ? ", " : ""), iv_arg);
+                    break;
+
+                default:
+                    fprintf(stderr, "pdisasm: Internal error! Unrecognized arg type 
+'%c'!\n", arg_type);
+                    exit(1);
+                    break;
+            }
+        }
+
+        printf("\n");
+    }
+
+    return;
+}
+
+
+/*
+** main()
+*/
+
+int
+main(int argc, char **argv) {
+    struct stat file_stat;
+    int         fd;
+    char *      packed;
+    long        packed_size;
+    PackFile * pf;
+
+    if (argc != 2) {
+        fprintf(stderr, "pdump: usage: pdump FILE\n");
+        return 1;
+    }
+
+    if (stat(argv[1], &file_stat)) {
+        printf("can't stat %s, code %i\n", argv[1], errno);
+        return 1;
+    }
+    fd = open(argv[1], O_RDONLY);
+    if (!fd) {
+        printf("Can't open, error %i\n", errno);
+        return 1;
+    }
+    
+    packed_size = file_stat.st_size;
+
+#ifndef HAS_HEADER_SYSMMAN
+    packed = mem_sys_allocate(packed_size);
+
+    if (!packed) {
+        printf("Can't allocate, code %i\n", errno);
+        return 1;
+    }
+
+    read(fd, (void*)packed, packed_size);
+#else
+    packed = mmap(0, packed_size, PROT_READ, MAP_SHARED, fd, 0);
+
+    if (!packed) {
+        printf("Can't mmap, code %i\n", errno);
+        return 1;
+    }
+#endif
+
+    pf = PackFile_new();
+
+    PackFile_unpack(pf, packed, packed_size);
+
+    disassemble(pf);
+
+    PackFile_DELETE(pf);
+
+    pf = NULL;
+    
+    return 0;
+}
+
+/*
+ * Local variables:
+ * c-indentation-style: bsd
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil 
+ * End:
+ *
+ * vim: expandtab shiftwidth=4:
+*/
Index: include/parrot/.cvsignore
===================================================================
RCS file: /home/perlcvs/parrot/include/parrot/.cvsignore,v
retrieving revision 1.2
diff -a -u -r1.2 .cvsignore
--- include/parrot/.cvsignore   2001/09/18 01:17:45     1.2
+++ include/parrot/.cvsignore   2001/10/03 12:24:53
@@ -1,3 +1,4 @@
 op.h
+op_info.h
 config.h
 interp_guts.h
Index: include/parrot/interpreter.h
===================================================================
RCS file: /home/perlcvs/parrot/include/parrot/interpreter.h,v
retrieving revision 1.6
diff -a -u -r1.6 interpreter.h
--- include/parrot/interpreter.h        2001/10/02 14:01:31     1.6
+++ include/parrot/interpreter.h        2001/10/03 12:24:53
@@ -15,6 +15,9 @@
 
 #include "parrot/parrot.h"
 
+#include "parrot/op_info.h"
+#include "parrot/interp_guts.h"
+
 struct Parrot_Interp {
     struct IReg *int_reg;            /* Current top of int reg stack */
     struct NReg *num_reg;            /* Current top of the float reg stack */
@@ -30,14 +33,23 @@
                                           /* variable area */
     struct Arenas *arena_base;            /* Pointer to this */
                                           /* interpreter's arena */
+#if 0
+    opcode_t *(*(*opcode_funcs)[2048])(); /* Opcode */
+                                          /* function table */
+
+    op_func_t * opcode_funcs;             /* Opcode funcs */
+#endif
+
+    op_info_t * opcode_info;              /* Opcode info (name, nargs, arg types) */
+                                          /* TODO: Why not 'op_info_table_t 
+opcode_info'? */
+
     opcode_t     *(**opcode_funcs)();     /* Opcode function table */
     STRING_FUNCS *(**string_funcs)();     /* String function table */
     INTVAL flags;                                /* Various interpreter flags
                                            that signal that runops
                                            should do something */
-
-    struct PackFile * code;                      /* The code we are executing */
 
+    struct PackFile * code;               /* The code we are executing */
 };
 
 #define PARROT_DEBUG_FLAG 0x01         /* Bit in the flags that says

Reply via email to