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