Skip to content

Commit

Permalink
Rewriting mkvmi to create a single template file
Browse files Browse the repository at this point in the history
  • Loading branch information
dmchurch authored and JanWielemaker committed May 11, 2021
1 parent bfa7113 commit 55d4fc8
Show file tree
Hide file tree
Showing 8 changed files with 597 additions and 98 deletions.
3 changes: 0 additions & 3 deletions src/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ pl-atom.ic
pl-atom.ih
pl-funct.ic
pl-funct.ih
pl-codetable.ic
pl-jumptable.ic
pl-vmi.h
defatom
mkvmi
vmi
Expand Down
14 changes: 9 additions & 5 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -217,13 +217,17 @@ else()
)
endif()

# FIXME: we should create these in the build directory
add_custom_target(
vmi-metadata
COMMAND ${PROG_MKVMI} ${CMAKE_CURRENT_SOURCE_DIR}
BYPRODUCTS pl-vmi.h pl-codetable.ic pl-jumptable.ic
DEPENDS ${PROG_MKVMI} pl-vmi.c
COMMENT "Generating VMI metadata"
DEPENDS pl-vmi.ih.stamp
)
add_custom_command(
COMMAND ${PROG_MKVMI} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND ${CMAKE_COMMAND} -E touch pl-vmi.ih.stamp
OUTPUT pl-vmi.ih.stamp
DEPENDS ${PROG_MKVMI} pl-vmi.c pl-vmi.ih
COMMENT "Generating VMI metadata into pl-vmi.ih"
VERBATIM
)

add_custom_target(
Expand Down
123 changes: 34 additions & 89 deletions src/mkvmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,16 @@
#include "pl-hash.c"

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
This program creates pl-codetable.c, pl-jumptable.ic and pl-vmi.h from
pl-vmi.c.
This program updates the autogenerated section of pl-vmi.ih from
pl-vmi.c and (the rest of) pl-vmi.ih.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

const char *program;
int verbose = 0;
const char *vmi_file = "pl-vmi.c";
const char *ctable_file = "pl-codetable.ic";
const char *jump_table = "pl-jumptable.ic";
const char *vmi_hdr = "pl-vmi.h";
const char *vmi_hdr = "pl-vmi.ih";
const char auto_begin[] = "/* AUTOGENERATED CONTENT FOLLOWS */";
const char auto_end[] = "/* AUTOGENERATED CONTENT ABOVE */";

#define MAX_VMI 1000

Expand Down Expand Up @@ -276,102 +276,43 @@ mystrlwr(char *to, const char *from) /* my*: Windows name conflict */
return to;
}


static int
emit_code_table(const char *to)
{ const char *tmp = "vmi.tmp";
emit_vmi_hdr(const char *to)
{ const char *tmp = "vmi.tmp";
FILE *in = fopen(to, "r");
FILE *out = fopen(tmp, "w");
int i;
char buf[1024];

fprintf(out, "/* File: %s\n\n", to);
fprintf(out, " This file provides a description of the virtual machine instructions\n");
fprintf(out, " and their arguments. It is used by pl-comp.c to facilitate the\n");
fprintf(out, " compiler and decompiler, as well as pl-wic.c to save/reload sequences\n");
fprintf(out, " of virtual machine instructions.\n");
while (fgets(buf, sizeof(buf), in))
{ fputs(buf, out);
if (strncmp(buf, auto_begin, sizeof(auto_begin) - 1) == 0)
break;
}
fprintf(out, "\n");
fprintf(out, " Note: this file is generated by %s from %s. DO NOT EDIT", program, vmi_file);
fprintf(out, " \n");
fprintf(out, "*/\n\n");
fprintf(out, "#include \"pl-incl.h\"\n\n");
fprintf(out, "const code_info codeTable[] = {\n");
fprintf(out, " /* {name, ID, flags, #args, argtype} */\n");
fprintf(out, "#define VM_SIGNATURE 0x%x\n\n", MurmurHashAligned2(synopsis, syn_size, 0x12345678));
fprintf(out, "/* Lowercase instruction names */\n\n");

for(i=0; i<vmi_count; i++)
{ char name[100];

fprintf(out, " {\"%s\", %s, %s, %s, {%s}},\n",
mystrlwr(name, vmi_list[i].name),
vmi_list[i].name,
vmi_list[i].flags,
vmi_list[i].argc,
vmi_list[i].args[0] ? vmi_list[i].args : "0");
fprintf(out, "#define VMLCASE_%s %s\n", vmi_list[i].name, mystrlwr(name, vmi_list[i].name));
}

fprintf(out, " { NULL, 0, 0, 0, {0} }\n");
fprintf(out, "};\n");
fclose(out);

return update_file(tmp, to);
}


static int
emit_jump_table(const char *to)
{ const char *tmp = "vmi.tmp";
FILE *out = fopen(tmp, "w");
int i;

fprintf(out, "/* File: %s\n\n", to);
fprintf(out, " This file provides the GCC-2 jump-labels to exploit GCC's\n");
fprintf(out, " support for threaded code.\n");
fprintf(out, "\n");
fprintf(out, " Note: this file is generated by %s from %s. DO NOT EDIT", program, vmi_file);
fprintf(out, " \n");
fprintf(out, "*/\n\n");

fprintf(out, "static void *jmp_table[] =\n");
fprintf(out, "{\n");


fprintf(out, "/* Instruction definitions */\n\n");
for(i=0; i<vmi_count; i++)
{ fprintf(out, " &&%s_LBL,\n", vmi_list[i].name);
}

fprintf(out, " NULL\n");
fprintf(out, "};\n");
fprintf(out, "_VMI(%s, %s, %s, (%s)) _VMI_SEP\n", vmi_list[i].name, vmi_list[i].flags, vmi_list[i].argc, vmi_list[i].args);

fclose(out);

return update_file(tmp, to);
}


static int
emit_code_defs(const char *to)
{ const char *tmp = "vmi.tmp";
FILE *out = fopen(tmp, "w");
int i;

fprintf(out, "/* File: %s\n\n", to);
fprintf(out, " This file provides the definition of type code.\n");
fprintf(out, "\n");
fprintf(out, " Note: this file is generated by %s from %s. DO NOT EDIT", program, vmi_file);
fprintf(out, " \n");
fprintf(out, "*/\n\n");

fprintf(out, "typedef enum\n");
fprintf(out, "{\n");


for(i=0; i<vmi_count; i++)
{ fprintf(out, " %s,\n", vmi_list[i].name);
while (fgets(buf, sizeof(buf), in))
{ if (strncmp(buf, auto_end, sizeof(auto_end) - 1) == 0)
break;
}
fprintf(out, "\n%s\n", auto_end);

fprintf(out, " VMI_END_LIST\n");
fprintf(out, "} vmi;\n\n");
fprintf(out, "#define I_HIGHEST ((int)VMI_END_LIST)\n");
fprintf(out, "#define VM_SIGNATURE 0x%x\n", MurmurHashAligned2(synopsis, syn_size, 0x12345678));
while (fgets(buf, sizeof(buf), in))
fputs(buf, out);

fclose(in);
fclose(out);

return update_file(tmp, to);
Expand All @@ -391,7 +332,7 @@ main(int argc, char **argv)
verbose = 1;
}

if ( argc == 1 )
if ( argc >= 1 )
snprintf(buf, sizeof(buf), "%s/%s", argv[0], vmi_file);
else
snprintf(buf, sizeof(buf), "%s", vmi_file);
Expand All @@ -401,9 +342,13 @@ main(int argc, char **argv)
if ( verbose )
fprintf(stderr, "Found %d VMs\n", vmi_count);

if ( emit_code_table(ctable_file) == 0 &&
emit_jump_table(jump_table) == 0 &&
emit_code_defs(vmi_hdr) == 0 )
if ( argc >= 2 )
{ snprintf(buf, sizeof(buf), "%s/%s", argv[1], vmi_hdr);
} else
{ snprintf(buf, sizeof(buf), "%s", vmi_hdr);
}

if ( emit_vmi_hdr(buf) == 0 )
return 0;
else
return 1;
Expand Down
16 changes: 16 additions & 0 deletions src/pl-codetable.ic
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* File: pl-codetable.ic

This file provides a description of the virtual machine instructions
and their arguments. It is used by pl-comp.c to facilitate the
compiler and decompiler, as well as pl-wic.c to save/reload sequences
of virtual machine instructions.
*/

#include "pl-incl.h"

const code_info codeTable[] = {
/* {name, ID, flags, #args, argtype} */
#define _VMI(Name, flags, nargs, argtypes) {VM_STRLOWER(Name), Name, flags, nargs, {VM_DEPAREN(argtypes)}},
#include "pl-vmi.ih"
{ NULL, 0, 0, 0, {0} }
};
12 changes: 12 additions & 0 deletions src/pl-jumptable.ic
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* File: pl-jumptable.ic

This file provides the GCC-2 jump-labels to exploit GCC's
support for threaded code.
*/

static void *jmp_table[] =
{
#define _VMI(Name,...) &&Name ## _LBL,
#include "pl-vmi.ih"
NULL
};
14 changes: 14 additions & 0 deletions src/pl-vmi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* File: pl-vmi.h
This file provides the definition of type code.
*/

typedef enum
{
#define _VMI(Name,...) Name,
#include "pl-vmi.ih"
VMI_END_LIST
} vmi;

#define I_HIGHEST ((int)VMI_END_LIST)
/* VM_SIGNATURE is defined in pl-vmi.h */
Loading

0 comments on commit 55d4fc8

Please sign in to comment.