Cleanup krk_disassembleInstruction

This commit is contained in:
K. Lange 2022-08-11 11:46:38 +09:00
parent fb57355178
commit 342ee04553
2 changed files with 135 additions and 106 deletions

View File

@ -10,6 +10,7 @@
#include "opcode_enum.h"
#ifndef KRK_DISABLE_DEBUG
#define NOOP (void)0
/**
* When tracing is enabled, we will present the elements on the stack with
@ -139,77 +140,111 @@ static int isJumpTarget(KrkCodeObject * func, size_t startPoint) {
#undef FORMAT_VALUE_MORE
}
#define SIMPLE(opc) case opc: fprintf(f, "%-16s ", opcodeClean(#opc)); size = 1; break;
#define CONSTANT(opc,more) case opc: { size_t constant = chunk->code[offset + 1]; \
fprintf(f, "%-16s %4d ", opcodeClean(#opc), (int)constant); \
krk_printValueSafe(f, chunk->constants.values[constant]); \
size = 2; more; break; } \
case opc ## _LONG: { size_t constant = (chunk->code[offset + 1] << 16) | \
(chunk->code[offset + 2] << 8) | (chunk->code[offset + 3]); \
fprintf(f, "%-16s %4d ", opcodeClean(#opc "_LONG"), (int)constant); \
krk_printValueSafe(f, chunk->constants.values[constant]); \
size = 4; more; break; }
#define OPERANDB(opc,more) case opc: { uint32_t operand = chunk->code[offset + 1]; \
fprintf(f, "%-16s %4d", opcodeClean(#opc), (int)operand); \
size = 2; more; break; }
#define OPERAND(opc,more) OPERANDB(opc,more) \
case opc ## _LONG: { uint32_t operand = (chunk->code[offset + 1] << 16) | \
(chunk->code[offset + 2] << 8) | (chunk->code[offset + 3]); \
fprintf(f, "%-16s %4d", opcodeClean(#opc "_LONG"), (int)operand); \
size = 4; more; fprintf(f,"\n"); break; }
#define JUMP(opc,sign) case opc: { uint16_t jump = (chunk->code[offset + 1] << 8) | \
(chunk->code[offset + 2]); \
fprintf(f, "%-16s %4d (to %d)", opcodeClean(#opc), (int)jump, (int)(offset + 3 sign jump)); \
size = 3; break; }
#define OPARGS FILE * f, const char * fullName, size_t * size, size_t * offset, KrkCodeObject * func, KrkChunk * chunk
#define OPARG_VALS f,fullName,size,offset,func,chunk
#define CLOSURE_MORE \
KrkCodeObject * function = AS_codeobject(chunk->constants.values[constant]); \
fprintf(f, " "); \
for (size_t j = 0; j < function->upvalueCount; ++j) { \
int isLocal = chunk->code[offset++ + size]; \
int index = chunk->code[offset++ + size]; \
if (isLocal & 2) { \
index = (index << 16) | (chunk->code[offset + size] << 8) | chunk->code[offset + 1 + size]; \
offset += 2; \
} \
if (isLocal & 1) { \
for (size_t i = 0; i < func->localNameCount; ++i) { \
if (func->localNames[i].id == (size_t)index && func->localNames[i].birthday <= offset && func->localNames[i].deathday >= offset) { \
fprintf(f, "%s", func->localNames[i].name->chars); \
break; \
} \
} \
} else { fprintf(f, "upvalue<%d>", index); } \
if (j + 1 != function->upvalueCount) fprintf(f, ", "); \
static void _print_opcode(OPARGS) {
fprintf(f, "%-16s ", opcodeClean(fullName));
}
static void _simple(OPARGS) {
_print_opcode(OPARG_VALS);
fprintf(f, " ");
*size = 1;
}
static void _constant(OPARGS, int isLong, void (*more)(OPARGS, size_t constant)) {
_print_opcode(OPARG_VALS);
size_t constant = isLong ? (chunk->code[*offset + 1] << 16) | (chunk->code[*offset + 2] << 8) | (chunk->code[*offset + 3]) : chunk->code[*offset + 1];
fprintf(f, "%4d ", (int)constant);
krk_printValueSafe(f, chunk->constants.values[constant]);
*size = isLong ? 4 : 2;
if (more) more(OPARG_VALS, constant);
}
static void _operand(OPARGS, int isLong, void (*more)(OPARGS, size_t constant)) {
_print_opcode(OPARG_VALS);
uint32_t operand = isLong ? (chunk->code[*offset + 1] << 16) | (chunk->code[*offset + 2] << 8) | (chunk->code[*offset + 3]) : chunk->code[*offset + 1];
fprintf(f, "%4d", (int)operand);
*size = isLong ? 4 : 2;
if (more) more(OPARG_VALS, operand);
}
static void _jump(OPARGS, int sign) {
_print_opcode(OPARG_VALS);
uint16_t jump = (chunk->code[*offset + 1] << 8) | (chunk->code[*offset + 2]);
fprintf(f, "%4d (to %d)", (int)jump, (int)(*offset + 3 + sign * jump));
*size = 3;
}
#undef NOOP
#define NOOP (NULL)
#define SIMPLE(opc) case opc: _simple(f,#opc,&size,&offset,func,chunk); break;
#define CONSTANT(opc,more) case opc: _constant(f,#opc,&size,&offset,func,chunk,0,more); break; \
case opc ## _LONG: _constant(f,#opc "_LONG",&size,&offset,func,chunk,1,more); break;
#define OPERAND(opc,more) case opc: _operand(f,#opc,&size,&offset,func,chunk,0,more); break; \
case opc ## _LONG: _operand(f,#opc "_LONG",&size,&offset,func,chunk,1,more); break;
#define JUMP(opc,sign) case opc: _jump(f,#opc,&size,&offset,func,chunk,sign 1); break;
#define CLOSURE_MORE _closure_more
static void _closure_more(OPARGS, size_t constant) {
KrkCodeObject * function = AS_codeobject(chunk->constants.values[constant]);
fprintf(f, " ");
for (size_t j = 0; j < function->upvalueCount; ++j) {
int isLocal = chunk->code[(*offset)++ + *size];
int index = chunk->code[(*offset)++ + *size];
if (isLocal & 2) {
index = (index << 16) | (chunk->code[*offset + *size] << 8) | chunk->code[*offset + 1 + *size];
offset += 2;
}
if (isLocal & 1) {
for (size_t i = 0; i < func->localNameCount; ++i) {
if (func->localNames[i].id == (size_t)index && func->localNames[i].birthday <= *offset && func->localNames[i].deathday >= *offset) {
fprintf(f, "%s", func->localNames[i].name->chars);
break;
}
}
} else { fprintf(f, "upvalue<%d>", index); }
if (j + 1 != function->upvalueCount) fprintf(f, ", ");
}
}
#define EXPAND_ARGS_MORE \
#define EXPAND_ARGS_MORE _expand_args_more
static void _expand_args_more(OPARGS, size_t operand) {
fprintf(f, " (%s)", operand == 0 ? "singleton" : (operand == 1 ? "list" : "dict"));
}
#define FORMAT_VALUE_MORE \
if (operand != 0) {\
int hasThing = 0; \
fprintf(f, " ("); \
if (operand & FORMAT_OP_EQ) { fprintf(f, "eq"); hasThing = 1; } \
if (operand & FORMAT_OP_STR) { fprintf(f, "%sstr", hasThing ? ", " : ""); hasThing = 1; } \
if (operand & FORMAT_OP_REPR) { fprintf(f, "%srepr", hasThing ? ", " : ""); hasThing = 1; } \
if (operand & FORMAT_OP_FORMAT) { fprintf(f, "%swith format", hasThing ? ", " : ""); } \
fprintf(f, ")"); \
}
#define FORMAT_VALUE_MORE _format_value_more
#define LOCAL_MORE \
if ((short int)operand < (func->requiredArgs)) { \
fprintf(f, " (%s, arg)", AS_CSTRING(func->requiredArgNames.values[operand])); \
} else if ((short int)operand < (func->requiredArgs + func->keywordArgs)) { \
fprintf(f, " (%s, kwarg))", AS_CSTRING(func->keywordArgNames.values[operand-func->requiredArgs])); \
} else { \
for (size_t i = 0; i < func->localNameCount; ++i) { \
if (func->localNames[i].id == operand && func->localNames[i].birthday <= offset && func->localNames[i].deathday >= offset) { \
fprintf(f, " (%s)", func->localNames[i].name->chars); \
break; \
} \
} \
static void _format_value_more(OPARGS, size_t operand) {
if (operand != 0) {
int hasThing = 0;
fprintf(f, " (");
if (operand & FORMAT_OP_EQ) { fprintf(f, "eq"); hasThing = 1; }
if (operand & FORMAT_OP_STR) { fprintf(f, "%sstr", hasThing ? ", " : ""); hasThing = 1; }
if (operand & FORMAT_OP_REPR) { fprintf(f, "%srepr", hasThing ? ", " : ""); hasThing = 1; }
if (operand & FORMAT_OP_FORMAT) { fprintf(f, "%swith format", hasThing ? ", " : ""); }
fprintf(f, ")");
}
}
#define LOCAL_MORE _local_more
static void _local_more(OPARGS, size_t operand) {
if ((short int)operand < (func->requiredArgs)) {
fprintf(f, " (%s, arg)", AS_CSTRING(func->requiredArgNames.values[operand]));
} else if ((short int)operand < (func->requiredArgs + func->keywordArgs)) {
fprintf(f, " (%s, kwarg))", AS_CSTRING(func->keywordArgNames.values[operand-func->requiredArgs]));
} else {
for (size_t i = 0; i < func->localNameCount; ++i) {
if (func->localNames[i].id == operand && func->localNames[i].birthday <= *offset && func->localNames[i].deathday >= *offset) {
fprintf(f, " (%s)", func->localNames[i].name->chars);
break;
}
}
}
}
size_t krk_disassembleInstruction(FILE * f, KrkCodeObject * func, size_t offset) {
KrkChunk * chunk = &func->chunk;
@ -261,6 +296,7 @@ size_t krk_disassembleInstruction(FILE * f, KrkCodeObject * func, size_t offset)
#undef LOCAL_MORE
#undef EXPAND_ARGS_MORE
#undef FORMAT_VALUE_MORE
#undef NOOP
struct BreakpointEntry {
KrkCodeObject * inFunction;
@ -640,6 +676,7 @@ KRK_Function(build) {
else return NONE_VAL();
}
#define NOOP (void)0
#define SIMPLE(opc) case opc: size = 1; break;
#define CONSTANT(opc,more) case opc: { constant = chunk->code[offset + 1]; size = 2; more; break; } \
case opc ## _LONG: { constant = (chunk->code[offset + 1] << 16) | \
@ -811,20 +848,12 @@ void krk_module_init_dis(void) {
#define CONSTANT(opc,more) OPCODE(opc) OPCODE(opc ## _LONG)
#define OPERAND(opc,more) OPCODE(opc) OPCODE(opc ## _LONG)
#define JUMP(opc,sign) OPCODE(opc)
#define CLOSURE_MORE
#define EXPAND_ARGS_MORE
#define FORMAT_VALUE_MORE
#define LOCAL_MORE
#include "opcodes.h"
#undef SIMPLE
#undef OPERANDB
#undef OPERAND
#undef CONSTANT
#undef JUMP
#undef CLOSURE_MORE
#undef LOCAL_MORE
#undef EXPAND_ARGS_MORE
#undef FORMAT_VALUE_MORE
}
#endif

View File

@ -1,47 +1,47 @@
CONSTANT(OP_CONSTANT,(void)0)
CONSTANT(OP_CONSTANT,NOOP)
SIMPLE(OP_BEGIN_FINALLY)
SIMPLE(OP_IS)
OPERAND(OP_POP_MANY, (void)0)
OPERAND(OP_POP_MANY, NOOP)
JUMP(OP_PUSH_TRY,+)
OPERAND(OP_GET_UPVALUE, (void)0)
OPERAND(OP_GET_UPVALUE, NOOP)
SIMPLE(OP_SWAP)
OPERAND(OP_CLOSE_MANY, (void)0)
OPERAND(OP_CLOSE_MANY, NOOP)
SIMPLE(OP_BITOR)
OPERAND(OP_SET_ADD, (void)0)
OPERAND(OP_SET_ADD, NOOP)
CONSTANT(OP_CLOSURE, CLOSURE_MORE)
SIMPLE(OP_SHIFTRIGHT)
OPERAND(OP_MAKE_SET, (void)0)
OPERAND(OP_MAKE_SET, NOOP)
SIMPLE(OP_CLOSE_UPVALUE)
CONSTANT(OP_IMPORT, (void)0)
CONSTANT(OP_IMPORT, NOOP)
JUMP(OP_JUMP,+)
JUMP(OP_JUMP_IF_FALSE_OR_POP,+)
OPERAND(OP_LIST_APPEND, (void)0)
OPERAND(OP_LIST_APPEND, NOOP)
SIMPLE(OP_INPLACE_SHIFTLEFT)
SIMPLE(OP_TRUE)
SIMPLE(OP_INPLACE_FLOORDIV)
SIMPLE(OP_INPLACE_BITAND)
CONSTANT(OP_SET_GLOBAL,(void)0)
CONSTANT(OP_SET_GLOBAL,NOOP)
SIMPLE(OP_RAISE)
OPERAND(OP_EXIT_LOOP, (void)0)
OPERAND(OP_MAKE_STRING, (void)0)
OPERAND(OP_EXIT_LOOP, NOOP)
OPERAND(OP_MAKE_STRING, NOOP)
SIMPLE(OP_INVOKE_AWAIT)
SIMPLE(OP_ADD)
SIMPLE(OP_SUBTRACT)
OPERAND(OP_CALL_METHOD, (void)0)
OPERAND(OP_CALL_METHOD, NOOP)
SIMPLE(OP_BREAKPOINT)
CONSTANT(OP_GET_GLOBAL,(void)0)
CONSTANT(OP_GET_GLOBAL,NOOP)
OPERAND(OP_SET_LOCAL_POP, LOCAL_MORE)
SIMPLE(OP_NEGATE)
SIMPLE(OP_INVOKE_ITER)
OPERAND(OP_FORMAT_VALUE, FORMAT_VALUE_MORE)
SIMPLE(OP_CLEANUP_WITH)
SIMPLE(OP_DIVIDE)
OPERAND(OP_SET_UPVALUE, (void)0)
OPERAND(OP_KWARGS, (void)0)
OPERAND(OP_SET_UPVALUE, NOOP)
OPERAND(OP_KWARGS, NOOP)
SIMPLE(OP_EQUAL)
SIMPLE(OP_UNSET)
JUMP(OP_LOOP_ITER,-)
CONSTANT(OP_SET_PROPERTY, (void)0)
CONSTANT(OP_SET_PROPERTY, NOOP)
SIMPLE(OP_FINALIZE)
OPERAND(OP_SET_LOCAL, LOCAL_MORE)
SIMPLE(OP_INVOKE_DELETE)
@ -53,49 +53,49 @@ SIMPLE(OP_FILTER_EXCEPT)
SIMPLE(OP_BITAND)
SIMPLE(OP_NONE)
SIMPLE(OP_POP)
CONSTANT(OP_IMPORT_FROM, (void)0)
OPERAND(OP_DICT_SET, (void)0)
CONSTANT(OP_IMPORT_FROM, NOOP)
OPERAND(OP_DICT_SET, NOOP)
JUMP(OP_TEST_ARG,+)
SIMPLE(OP_INVOKE_GETTER)
SIMPLE(OP_INVOKE_CONTAINS)
SIMPLE(OP_INVOKE_SETTER)
SIMPLE(OP_INPLACE_DIVIDE)
CONSTANT(OP_GET_SUPER, (void)0)
CONSTANT(OP_GET_SUPER, NOOP)
SIMPLE(OP_YIELD)
OPERAND(OP_TUPLE, (void)0)
OPERAND(OP_TUPLE, NOOP)
SIMPLE(OP_INPLACE_BITOR)
SIMPLE(OP_INPLACE_MODULO)
SIMPLE(OP_POS)
CONSTANT(OP_DEFINE_GLOBAL,(void)0)
CONSTANT(OP_DEFINE_GLOBAL,NOOP)
SIMPLE(OP_LESS)
SIMPLE(OP_BITXOR)
SIMPLE(OP_INPLACE_SUBTRACT)
OPERAND(OP_SLICE, (void)0)
OPERAND(OP_SLICE, NOOP)
SIMPLE(OP_NOT)
OPERAND(OP_CALL, (void)0)
OPERAND(OP_CALL, NOOP)
JUMP(OP_PUSH_WITH,+)
SIMPLE(OP_GREATER_EQUAL)
CONSTANT(OP_CLASS_PROPERTY, (void)0)
CONSTANT(OP_CLASS_PROPERTY, NOOP)
SIMPLE(OP_INPLACE_ADD)
CONSTANT(OP_GET_METHOD, (void)0)
CONSTANT(OP_CLASS,(void)0)
CONSTANT(OP_GET_METHOD, NOOP)
CONSTANT(OP_CLASS,NOOP)
SIMPLE(OP_LESS_EQUAL)
SIMPLE(OP_DOCSTRING)
SIMPLE(OP_MATMUL)
SIMPLE(OP_MODULO)
OPERAND(OP_MAKE_DICT, (void)0)
OPERAND(OP_MAKE_DICT, NOOP)
SIMPLE(OP_INPLACE_BITXOR)
SIMPLE(OP_INPLACE_MATMUL)
CONSTANT(OP_DEL_GLOBAL,(void)0)
CONSTANT(OP_DEL_GLOBAL,NOOP)
SIMPLE(OP_INPLACE_SHIFTRIGHT)
OPERAND(OP_UNPACK, (void)0)
OPERAND(OP_REVERSE, (void)0)
CONSTANT(OP_GET_PROPERTY, (void)0)
OPERAND(OP_UNPACK, NOOP)
OPERAND(OP_REVERSE, NOOP)
CONSTANT(OP_GET_PROPERTY, NOOP)
SIMPLE(OP_GREATER)
SIMPLE(OP_FALSE)
SIMPLE(OP_FLOORDIV)
OPERAND(OP_DUP,(void)0)
CONSTANT(OP_DEL_PROPERTY,(void)0)
OPERAND(OP_DUP,NOOP)
CONSTANT(OP_DEL_PROPERTY,NOOP)
SIMPLE(OP_MULTIPLY)
JUMP(OP_LOOP,-)
SIMPLE(OP_BITNEGATE)
@ -103,7 +103,7 @@ SIMPLE(OP_RETURN)
SIMPLE(OP_POW)
SIMPLE(OP_INPLACE_POW)
JUMP(OP_YIELD_FROM,+)
OPERAND(OP_MAKE_LIST, (void)0)
OPERAND(OP_MAKE_LIST, NOOP)
OPERAND(OP_GET_LOCAL, LOCAL_MORE)
SIMPLE(OP_END_FINALLY)
SIMPLE(OP_INPLACE_MULTIPLY)