命令ハッシュ表の構造を変更 v0.5p1
authorj8takagi <j8takagi@nifty.com>
Sat, 18 Aug 2018 16:25:14 +0000 (01:25 +0900)
committerj8takagi <j8takagi@nifty.com>
Sat, 18 Aug 2018 16:25:14 +0000 (01:25 +0900)
12 files changed:
.gitignore
Makefile
include/struct.h
src/casl2.c
src/comet2monitor.c
src/disassemble.c
src/exec.c
src/monitor.c
src/struct.c
test/system/Makefile
test/unit/getcmdcode/Makefile
test/unit/getcmdcode/cmd.c

index f72eba1..0b66677 100644 (file)
@@ -18,3 +18,4 @@ core
 .DS_Store
 *.bak
 fontconfig
+*.log.core*
index df6cab7..e88b56f 100644 (file)
--- 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
 
index ed58762..ffc448e 100644 (file)
@@ -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);
 
 /**
- * å\90\8då\89\8dã\81¨ã\82¿ã\82¤ã\83\97ã\81\8cã\82­ã\83¼ã\81®å\91½ä»¤ã\83\8fã\83\83ã\82·ã\83¥è¡¨ã\82\92解æ\94¾ã\81\99ã\82\8b
+ * 命令ハッシュ表を解放する
  */
-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の終端 */
index 36d5703..68cbb24 100644 (file)
@@ -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;
index b961711..3f9ed7a 100644 (file)
@@ -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;
index 8f3c9d7..a97a042 100644 (file)
@@ -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;
 }
index c7c125e..048f223 100644 (file)
@@ -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);
     }
index 4278c6a..9fe71f5 100644 (file)
@@ -359,7 +359,7 @@ void monitor()
         if(cmdtype == MONQUIT) {
             shutdown();
             freebps();
-            free_code_cmdtype();
+            free_cmdtable(HASH_CODE);
             freecerr();
             exit(0);
         }
index 4e38f2e..f6d4128 100644 (file)
@@ -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)
 }
 
 /**
- * å\90\8då\89\8dã\81¨ã\82¿ã\82¤ã\83\97ã\81\8cã\82­ã\83¼ã\81®å\91½ä»¤ã\83\8fã\83\83ã\82·ã\83¥è¡¨ã\82\92ä½\9cæ\88\90ã\81\99ã\82\8b
+ * 命令ハッシュ表を作成する
  */
-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仮想マシンのリセット
  */
index 833b8fe..fe87d96 100644 (file)
@@ -12,6 +12,9 @@ check:
 smoke:
        $(MAKE) -sC casl2_smoke check
 
+smoke-valgrind:
+       $(MAKE) -sC casl2_smoke valgrind
+
 valgrind:
        @$(call make_dirs,$(CMD),$@; )
 
index 9d22ef3..05e649e 100644 (file)
@@ -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 $@ $^
index c1d33ff..a479173 100644 (file)
@@ -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;
 }