From: j8takagi Date: Sat, 18 Aug 2018 16:25:14 +0000 (+0900) Subject: 命令ハッシュ表の構造を変更 X-Git-Tag: v0.5p1 X-Git-Url: http://j8takagi.net/cgi-bin/gitweb.cgi?p=YACASL2.git;a=commitdiff_plain;h=refs%2Ftags%2Fv0.5p1;hp=be496380efb4018b38076cfadb4b790fa388a1e3 命令ハッシュ表の構造を変更 --- diff --git a/.gitignore b/.gitignore index f72eba1..0b66677 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ core .DS_Store *.bak fontconfig +*.log.core* diff --git a/Makefile b/Makefile index df6cab7..e88b56f 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ CMDFILES := casl2 comet2 dumpword casl2rev comet2monitor all: build INSTALL gtags -build: +build: version $(MAKE) -C src all @(for f in $(CMDFILES); do if test ! -e $$f -o src/$$f -nt $$f; then $(CP) src/$$f $$f; fi; done) @@ -63,6 +63,9 @@ check: smoke: $(MAKE) -sC test/system smoke +smoke-valgrind: + $(MAKE) -sC test/system smoke-valgrind + valgrind: $(MAKE) -sC test/system valgrind diff --git a/include/struct.h b/include/struct.h index ed58762..ffc448e 100644 --- a/include/struct.h +++ b/include/struct.h @@ -53,6 +53,15 @@ typedef struct { */ extern SYSTEM *sys; +/** + * 命令ハッシュ表のハッシュの種類 + */ +typedef enum { + HASH_CMDTYPE, + HASH_CODE, + HASH_MAX, +} CMDTAB_HASH; + /** * COMET II 命令 * 命令タイプは、オペランドにより5種類に分類 @@ -145,25 +154,24 @@ void reset(int memsize, int clocks); void shutdown(); /** - * 名前とタイプがキーの命令ハッシュ表を作成する - */ -bool create_cmdtype_code(); - -/** - * 命令の名前とタイプから、命令コードを返す - * 無効な場合は0xFFFFを返す + * @brief 命令ハッシュ表を作成する + * + * @return なし + * + * @param hash ハッシュ値 */ -WORD getcmdcode(const char *cmd, CMDTYPE type); +bool create_cmdtable(CMDTAB_HASH hash); /** - * 名前とタイプがキーの命令ハッシュ表を解放する + * 命令ハッシュ表を解放する */ -void free_cmdtype_code(); +void free_cmdtable(CMDTAB_HASH hash); /** - * コードがキーの命令ハッシュ表を作成する + * 命令の名前とタイプから、命令コードを返す + * 無効な場合は0xFFFFを返す */ -bool create_code_cmdtype(); +WORD getcmdcode(const char *cmd, CMDTYPE type); /** * 命令コードから命令の関数ポインタを返す @@ -180,9 +188,4 @@ CMDTYPE getcmdtype(WORD code); */ char *getcmdname(WORD code); -/** - * コードがキーの命令ハッシュ表を解放する - */ -void free_code_cmdtype(); - #endif /* YACASL2_CASL2_INCLUDEDの終端 */ diff --git a/src/casl2.c b/src/casl2.c index 36d5703..68cbb24 100644 --- a/src/casl2.c +++ b/src/casl2.c @@ -145,7 +145,7 @@ int main(int argc, char *argv[]) freecerr(); /* エラーの解放 */ exit(1); } - create_cmdtype_code(); /* 命令の名前とタイプがキーのハッシュ表を作成 */ + create_cmdtable(HASH_CMDTYPE); /* 命令の名前とタイプがキーのハッシュ表を作成 */ reset(memsize, clocks); /* 仮想マシンCOMET IIのリセット */ for(i = 0; i < argc - optind; i++) { /* 引数からファイル名配列を取得 */ af[i] = argv[optind + i]; @@ -165,7 +165,7 @@ int main(int argc, char *argv[]) } casl2fin: shutdown(); /* 仮想マシンCOMET IIのシャットダウン */ - free_cmdtype_code(); + free_cmdtable(HASH_CMDTYPE); stat = (cerr->num == 0) ? 0 : 1; freecerr(); /* エラーの解放 */ return stat; diff --git a/src/comet2monitor.c b/src/comet2monitor.c index b961711..3f9ed7a 100644 --- a/src/comet2monitor.c +++ b/src/comet2monitor.c @@ -52,14 +52,14 @@ int main(int argc, char *argv[]) addcerrlist_load(); addcerrlist_exec(); - create_cmdtype_code(); + create_cmdtable(HASH_CMDTYPE); reset(memsize, clocks); /* COMET II仮想マシンのリセット */ execptr->start = 0; execmode.monitor = true; exec(); /* プログラム実行 */ shutdown(); - free_cmdtype_code(); + free_cmdtable(HASH_CMDTYPE); stat = (cerr->num == 0) ? 0 : 1; freecerr(); /* エラーの解放 */ return stat; diff --git a/src/disassemble.c b/src/disassemble.c index 8f3c9d7..a97a042 100644 --- a/src/disassemble.c +++ b/src/disassemble.c @@ -188,7 +188,7 @@ bool disassemble_file(const char *file) return false; } - create_code_cmdtype(); /* 命令のコードとタイプがキーのハッシュ表を作成 */ + create_cmdtable(HASH_CODE); /* 命令のコードとタイプがキーのハッシュ表を作成 */ fprintf(stdout, "MAIN START\n"); for(word = fgetword(fp); !feof(fp); i++, word = fgetword(fp)) { @@ -218,7 +218,7 @@ bool disassemble_file(const char *file) fprintf(stdout, "\n"); } fprintf(stdout, " END\n"); - free_code_cmdtype(); + free_cmdtable(HASH_CODE); fclose(fp); return stat; } diff --git a/src/exec.c b/src/exec.c index c7c125e..048f223 100644 --- a/src/exec.c +++ b/src/exec.c @@ -768,7 +768,8 @@ void exec() char *s; const char *monmsg = "COMET II machine code monitor. Type ? for help.\n"; - create_code_cmdtype(); /* 命令のコードとタイプがキーのハッシュ表を作成 */ + create_cmdtable(HASH_CODE); /* 命令のコードとタイプがキーのハッシュ表を作成 */ + if(execmode.trace == true) { fprintf(stdout, "\nExecuting machine codes\n"); } @@ -837,7 +838,7 @@ void exec() } execfin: freebps(); - free_code_cmdtype(); /* 命令のコードとタイプがキーのハッシュ表を解放 */ + free_cmdtable(HASH_CODE); /* 命令のコードとタイプがキーのハッシュ表を解放 */ if(cerr->num > 0) { fprintf(stderr, "Execute error - %d: %s\n", cerr->num, cerr->msg); } diff --git a/src/monitor.c b/src/monitor.c index 4278c6a..9fe71f5 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -359,7 +359,7 @@ void monitor() if(cmdtype == MONQUIT) { shutdown(); freebps(); - free_code_cmdtype(); + free_cmdtable(HASH_CODE); freecerr(); exit(0); } diff --git a/src/struct.c b/src/struct.c index 4e38f2e..f6d4128 100644 --- a/src/struct.c +++ b/src/struct.c @@ -70,7 +70,17 @@ enum { /** * ハッシュ表 */ -static CMDTAB *cmdtype_code[CMDTABSIZE], *code_cmdtype[CMDTABSIZE]; +static CMDTAB *cmdtab[HASH_MAX][CMDTABSIZE]; + +/** + * 命令の名前とタイプからハッシュ値を生成する + */ +unsigned hash_cmdtype(const char *cmd, CMDTYPE type); + +/** + * 命令コードからハッシュ値を生成する + */ +unsigned hash_code(WORD code); /** * 命令の名前とタイプからハッシュ値を生成する @@ -98,24 +108,45 @@ unsigned hash_cmdtype(const char *cmd, CMDTYPE type) } /** - * 名前とタイプがキーの命令ハッシュ表を作成する + * 命令ハッシュ表を作成する */ -bool create_cmdtype_code() +bool create_cmdtable(CMDTAB_HASH hash) { CMDTAB *p; unsigned hashval; int i; for(i = 0; i < comet2cmdsize; i++) { - hashval = hash_cmdtype(comet2cmd[i].name, comet2cmd[i].type); /* ハッシュ値の生成 */ - p = malloc_chk(sizeof(CMDTAB), "cmdtype_code"); + p = malloc_chk(sizeof(CMDTAB), "create_cmdtable.p"); p->cmd = &comet2cmd[i]; - p->next = cmdtype_code[hashval]; /* ハッシュ表に値を追加 */ - cmdtype_code[hashval] = p; + if(hash == HASH_CMDTYPE) { + hashval = hash_cmdtype(comet2cmd[i].name, comet2cmd[i].type); + } else if(hash == HASH_CODE) { + hashval = hash_code((&comet2cmd[i])->code); + } + p->next = cmdtab[hash][hashval]; + cmdtab[hash][hashval] = p; } return true; } +/** + * 命令ハッシュ表を解放する + */ +void free_cmdtable(CMDTAB_HASH hash) +{ + int i; + CMDTAB *p, *q; + + for(i = 0; i < CMDTABSIZE; i++) { + for(p = cmdtab[hash][i]; p != NULL; p = q) { + q = p->next; + cmdtab[hash][i] = NULL; + FREE(p); + } + } +} + /** * 命令の名前とタイプから、命令コードを返す\n * 無効な場合は0xFFFFを返す @@ -126,7 +157,7 @@ WORD getcmdcode(const char *cmd, CMDTYPE type) WORD w = 0xFFFF; assert(cmd != NULL); - for(p = cmdtype_code[hash_cmdtype(cmd, type)]; p != NULL; p = p->next) { + for(p = cmdtab[HASH_CMDTYPE][hash_cmdtype(cmd, type)]; p != NULL; p = p->next) { if(strcmp(cmd, p->cmd->name) == 0 && type == p->cmd->type) { w = p->cmd->code; break; @@ -135,22 +166,6 @@ WORD getcmdcode(const char *cmd, CMDTYPE type) return w; } -/** - * 名前とタイプがキーの命令ハッシュ表を解放する - */ -void free_cmdtype_code() -{ - int i; - CMDTAB *p, *q; - - for(i = 0; i < CMDTABSIZE; i++) { - for(p = cmdtype_code[i]; p != NULL; p = q) { - q = p->next; - FREE(p); - } - } -} - /** * 命令コードからハッシュ値を生成する */ @@ -168,25 +183,6 @@ unsigned hash_code(WORD code) return h; } -/** - * コードがキーの命令ハッシュ表を作成する - */ -bool create_code_cmdtype() -{ - CMDTAB *p; - unsigned hashval; - int i; - - for(i = 0; i < comet2cmdsize; i++) { - hashval = hash_code((&comet2cmd[i])->code); /* ハッシュ値の生成 */ - p = malloc_chk(sizeof(CMDTAB), "code_cmdtype"); - p->cmd = &comet2cmd[i]; - p->next = code_cmdtype[hashval]; /* ハッシュ表に値を追加 */ - code_cmdtype[hashval] = p; - } - return true; -} - /** * 命令コードから命令の関数ポインタを返す */ @@ -195,7 +191,7 @@ const void (*getcmdptr(WORD code)) CMDTAB *t; const void *ptr = NULL; - for(t = code_cmdtype[hash_code(code)]; t != NULL; t = t->next) { + for(t = cmdtab[HASH_CODE][hash_code(code)]; t != NULL; t = t->next) { if(code == t->cmd->code) { ptr = t->cmd->ptr; break; @@ -212,7 +208,7 @@ CMDTYPE getcmdtype(WORD code) CMDTAB *t; CMDTYPE type = NONE; - for(t = code_cmdtype[hash_code(code)]; t != NULL; t = t->next) { + for(t = cmdtab[HASH_CODE][hash_code(code)]; t != NULL; t = t->next) { if(code == t->cmd->code) { type = t->cmd->type; break; @@ -229,7 +225,7 @@ char *getcmdname(WORD code) CMDTAB *t; char *cmd = NULL; - for(t = code_cmdtype[hash_code(code)]; t != NULL; t = t->next) { + for(t = cmdtab[HASH_CODE][hash_code(code)]; t != NULL; t = t->next) { if(code == t->cmd->code) { cmd = t->cmd->name; break; @@ -250,21 +246,6 @@ char *grstr(WORD word) return str; } -/** - * コードがキーの命令ハッシュ表を解放する - */ -void free_code_cmdtype() -{ - int i; - CMDTAB *p, *q; - for(i = 0; i < CMDTABSIZE; i++) { - for(p = code_cmdtype[i]; p != NULL; p = q) { - q = p->next; - FREE(p); - } - } -} - /** * COMET II仮想マシンのリセット */ diff --git a/test/system/Makefile b/test/system/Makefile index 833b8fe..fe87d96 100644 --- a/test/system/Makefile +++ b/test/system/Makefile @@ -12,6 +12,9 @@ check: smoke: $(MAKE) -sC casl2_smoke check +smoke-valgrind: + $(MAKE) -sC casl2_smoke valgrind + valgrind: @$(call make_dirs,$(CMD),$@; ) diff --git a/test/unit/getcmdcode/Makefile b/test/unit/getcmdcode/Makefile index 9d22ef3..05e649e 100644 --- a/test/unit/getcmdcode/Makefile +++ b/test/unit/getcmdcode/Makefile @@ -9,7 +9,7 @@ CFLAGS := -Wall CMDSRC_FILE := cmd.c TARGETDIR := ../../../src INCLUDEDIR := ../../../include -TESTTARGET_FILES := $(TARGETDIR)/hash.c $(TARGETDIR)/exec.c $(TARGETDIR)/struct.c $(TARGETDIR)/dump.c $(TARGETDIR)/word.c $(TARGETDIR)/cmem.c $(TARGETDIR)/cerr.c # Set test target files +TESTTARGET_FILES := $(TARGETDIR)/hash.c $(TARGETDIR)/exec.c $(TARGETDIR)/struct.c $(TARGETDIR)/dump.c $(TARGETDIR)/word.c $(TARGETDIR)/cmem.c $(TARGETDIR)/cerr.c $(TARGETDIR)/monitor.c $(TARGETDIR)/disassemble.c $(TARGETDIR)/assemble.c $(TARGETDIR)/label.c $(TARGETDIR)/token.c # Set test target files $(CMD_FILE): $(CMDSRC_FILE) $(TESTTARGET_FILES) $(CC) $(CFLAGS) -I $(INCLUDEDIR) -o $@ $^ diff --git a/test/unit/getcmdcode/cmd.c b/test/unit/getcmdcode/cmd.c index c1d33ff..a479173 100644 --- a/test/unit/getcmdcode/cmd.c +++ b/test/unit/getcmdcode/cmd.c @@ -2,6 +2,7 @@ #include "struct.h" #include "cerr.h" #include "exec.h" +#include "monitor.h" int main(){ int i; @@ -25,7 +26,7 @@ int main(){ { "PUSH", ADR_X }, { "POP", R_ }, { "CALL", ADR_X }, { "SVC", ADR_X }, { "RET", NONE } }; - create_cmdtype_code(); + create_cmdtable(HASH_CMDTYPE); cerr_init(); for(i = 0; i < sizeof(cmdcodelist)/sizeof(cmdcodelist[0]); i++) { code = getcmdcode(cmdcodelist[i].cmd, cmdcodelist[i].type); @@ -35,6 +36,6 @@ int main(){ } } freecerr(); - free_cmdtype_code(); + free_cmdtable(HASH_CMDTYPE); return 0; }