Browse Source

Improved gravity_disassemble output.

Marco Bambini 7 years ago
parent
commit
968534c5d4
2 changed files with 81 additions and 129 deletions
  1. 80 128
      src/utils/gravity_debug.c
  2. 1 1
      src/utils/gravity_debug.h

+ 80 - 128
src/utils/gravity_debug.c

@@ -46,16 +46,16 @@ const char *opcode_name (opcode_t op) {
 
 #define DUMP_VM_RAW(buffer, bindex, ...)				bindex += snprintf(&buffer[bindex], balloc-bindex, __VA_ARGS__);
 
-const char *gravity_disassemble (const char *bcode, uint32_t blen, bool deserialize) {
+const char *gravity_disassemble (gravity_vm *vm, gravity_function_t *f, const char *bcode, uint32_t blen, bool deserialize) {
 	uint32_t	*ip = NULL;
 	uint32_t	pc = 0, inst = 0, ninsts = 0;
 	opcode_t	op;
-
+	
 	const int	rowlen = 256;
 	uint32_t	bindex = 0;
 	uint32_t	balloc = 0;
 	char		*buffer = NULL;
-
+	
 	if (deserialize) {
 		// decode textual buffer to real bytecode
 		ip = gravity_bytecode_deserialize(bcode, blen, &ninsts);
@@ -64,41 +64,57 @@ const char *gravity_disassemble (const char *bcode, uint32_t blen, bool deserial
 		ip = (uint32_t *)bcode;
 		ninsts = blen;
 	}
-
+		
 	// allocate a buffer big enought to fit all disassembled bytecode
 	// I assume that each instruction (each row) will be 256 chars long
 	balloc = ninsts * rowlen;
 	buffer = mem_alloc(NULL, balloc);
 	if (!buffer) goto abort_disassemble;
-
+		
 	// conversion loop
 	while (pc < ninsts) {
 		inst = *ip++;
 		op = (opcode_t)OPCODE_GET_OPCODE(inst);
-
+		
+        // for fixed N spaces in opcode name
+        // replace %s with %-Ns
 		switch (op) {
 			case NOP: {
-				DUMP_VM(buffer, bindex, "NOP");
-				break;
-			}
-
-			case MOVE: {
+				DUMP_VM(buffer, bindex, "%s", opcode_name(op));
+				break;
+			}
+				
+			case MOVE:
+            case LOADG:
+            case LOADU:
+            case STOREG:
+            case STOREU:
+            case JUMPF:
+            case MAPNEW:
+            case LISTNEW:
+            case CLOSURE: {
 				OPCODE_GET_ONE8bit_ONE18bit(inst, const uint32_t r1, const uint32_t r2);
-				DUMP_VM(buffer, bindex, "MOVE %d %d", r1, r2);
+				DUMP_VM(buffer, bindex, "%s %d %d", opcode_name(op), r1, r2);
 				break;
 			}
-
+				
 			case LOADI: {
-				//OPCODE_GET_ONE8bit_ONE18bit(inst, uint32_t r1, int32_t value); if no support for signed int
 				OPCODE_GET_ONE8bit_SIGN_ONE17bit(inst, const uint32_t r1, const int32_t value);
-				DUMP_VM(buffer, bindex, "LOADI %d %d", r1, value);
+				DUMP_VM(buffer, bindex, "%s %d %d", opcode_name(op), r1, value);
 				break;
 			}
 
 			case LOADK: {
 				OPCODE_GET_ONE8bit_ONE18bit(inst, const uint32_t r1, const uint32_t index);
 				if (index < CPOOL_INDEX_MAX) {
-					DUMP_VM(buffer, bindex, "LOADK %d %d", r1, index);
+					DUMP_VM(buffer, bindex, "%s %d %d", opcode_name(op), r1, index);
+                    if (f) {
+                        char b[2018];
+                        gravity_value_t constant = gravity_function_cpool_get(f, index);
+                        gravity_value_dump(vm, constant, b, sizeof(b));
+                        --bindex; // to replace the \n character
+                        DUMP_VM_RAW(buffer, bindex, "\t\t;%s\n", b);
+                    }
 				} else {
 					const char *special;
 					switch (index) {
@@ -111,171 +127,107 @@ const char *gravity_disassemble (const char *bcode, uint32_t blen, bool deserial
 						case CPOOL_VALUE_FUNC: special = "_FUNC"; break;
 						default: special = "Invalid index in LOADK opcode"; break;
 					}
-					DUMP_VM(buffer, bindex, "LOADK %d %s", r1, special);
+					DUMP_VM(buffer, bindex, "%s %d %s", opcode_name(op), r1, special);
 				}
 				break;
 			}
-
-			case LOADG: {
-				OPCODE_GET_ONE8bit_ONE18bit(inst, uint32_t r1, int32_t index);
-				DUMP_VM(buffer, bindex, "LOADG %d %d", r1, index);
-				break;
-			}
-
+			
 			case LOAD:
 			case LOADS:
-			case LOADAT: {
-				OPCODE_GET_TWO8bit_ONE10bit(inst, const uint32_t r1, const uint32_t r2, const uint32_t r3);
-				DUMP_VM(buffer, bindex, "%s %d %d %d", (op == LOAD) ? "LOAD" : "LOADAT", r1, r2, r3);
-				break;
-			}
-
-			case LOADU: {
-				OPCODE_GET_ONE8bit_ONE18bit(inst, const uint32_t r1, const uint32_t r2);
-				DUMP_VM(buffer, bindex, "LOADU %d %d", r1, r2);
-				break;
-			}
-
-			case STOREG: {
-				OPCODE_GET_ONE8bit_ONE18bit(inst, uint32_t r1, int32_t index);
-				DUMP_VM(buffer, bindex, "STOREG %d %d", r1, index);
-				break;
-			}
-
-			case STOREU: {
-				OPCODE_GET_ONE8bit_ONE18bit(inst, const uint32_t r1, const uint32_t r2);
-				DUMP_VM(buffer, bindex, "STOREU %d %d", r1, r2);
-				break;
-			}
-
-			case STORE:
-			case STOREAT: {
-				OPCODE_GET_TWO8bit_ONE10bit(inst, const uint32_t r1, const uint32_t r2, const uint32_t r3);
-				DUMP_VM(buffer, bindex, "%s %d %d %d", (op == STORE) ? "STORE" : "STOREAT", r1, r2, r3);
-				break;
-			}
-
-			case EQQ:
-			case NEQQ:
-			case ISA:
-			case MATCH:
-			case LT:
-			case GT:
-			case EQ:
-			case LEQ:
-			case GEQ:
-			case NEQ: {
+			case LOADAT:
+            case STORE:
+            case STOREAT:
+            case EQQ:
+            case NEQQ:
+            case ISA:
+            case MATCH:
+            case LT:
+            case GT:
+            case EQ:
+            case LEQ:
+            case GEQ:
+            case NEQ:
+            case LSHIFT:
+            case RSHIFT:
+            case BAND:
+            case BOR:
+            case BXOR:
+            case ADD:
+            case SUB:
+            case DIV:
+            case MUL:
+            case REM:
+            case AND:
+            case OR: {
 				OPCODE_GET_TWO8bit_ONE10bit(inst, const uint32_t r1, const uint32_t r2, const uint32_t r3);
 				DUMP_VM(buffer, bindex, "%s %d %d %d", opcode_name(op), r1, r2, r3);
 				break;
 			}
-
-			// binary operators
-			case LSHIFT:
-			case RSHIFT:
-			case BAND:
-			case BOR:
-			case BXOR:
-			case ADD:
-			case SUB:
-			case DIV:
-			case MUL:
-			case REM:
-			case AND:
-			case OR: {
-				OPCODE_GET_TWO8bit_ONE10bit(inst, const uint32_t r1, const uint32_t r2, const uint32_t r3);
-				DUMP_VM(buffer, bindex, "%s %d %d %d", opcode_name(op), r1, r2, r3);
-				break;
-			}
-
+				
 			// unary operators
 			case BNOT:
 			case NEG:
 			case NOT: {
 				OPCODE_GET_TWO8bit_ONE10bit(inst, const uint32_t r1, const uint32_t r2, const uint32_t r3);
 				#pragma unused(r3)
-				DUMP_VM(buffer, bindex, "%s %d %d %d", opcode_name(op), r1, r2, r3);
+				DUMP_VM(buffer, bindex, "%s %d %d", opcode_name(op), r1, r2);
 				break;
 			}
-
+			
 			case RANGENEW: {
 				OPCODE_GET_TWO8bit_ONE10bit(inst, const uint32_t r1, const uint32_t r2, const uint32_t r3);
 				DUMP_VM(buffer, bindex, "%s %d %d %d", opcode_name(op), r1, r2, r3);
 				break;
 			}
-
-			case JUMPF: {
-				OPCODE_GET_ONE8bit_ONE18bit(inst, const uint32_t r1, const int32_t value);
-				DUMP_VM(buffer, bindex, "JUMPF %d %d", r1, value);
-				break;
-			}
-
+				
 			case JUMP: {
 				OPCODE_GET_ONE26bit(inst, const uint32_t value);
-				DUMP_VM(buffer, bindex, "JUMP %d", value);
+				DUMP_VM(buffer, bindex, "%s %d", opcode_name(op), value);
 				break;
 			}
-
+				
 			case CALL: {
 				// CALL A B C => R(A) = B(C0... CN)
 				OPCODE_GET_THREE8bit(inst, const uint32_t r1, const uint32_t r2, uint32_t r3);
-				DUMP_VM(buffer, bindex, "CALL %d %d %d", r1, r2, r3);
+				DUMP_VM(buffer, bindex, "%s %d %d %d", opcode_name(op), r1, r2, r3);
 				break;
 			}
-
+				
 			case RET0:
 			case RET: {
 				if (op == RET0) {
-					DUMP_VM(buffer, bindex, "RET0");
+					DUMP_VM(buffer, bindex, "%s", opcode_name(op));
 				} else {
 					OPCODE_GET_ONE8bit(inst, const uint32_t r1);
-					DUMP_VM(buffer, bindex, "RET %d", r1);
+					DUMP_VM(buffer, bindex, "%s %d", opcode_name(op), r1);
 				}
 				break;
 			}
-
+				
 			case HALT: {
-				DUMP_VM(buffer, bindex, "HALT");
+				DUMP_VM(buffer, bindex, "%s", opcode_name(op));
 				break;
 			}
-
+				
 			case SWITCH: {
 				DUMP_VM(buffer, bindex, "SWITCH instruction not yet implemented");
 				break;
 			}
-
-			case MAPNEW: {
-				OPCODE_GET_ONE8bit_ONE18bit(inst, const uint32_t r1, const uint32_t n);
-				DUMP_VM(buffer, bindex, "MAPNEW %d %d", r1, n);
-				break;
-			}
-
-			case LISTNEW: {
-				OPCODE_GET_ONE8bit_ONE18bit(inst, const uint32_t r1, const uint32_t n);
-				DUMP_VM(buffer, bindex, "LISTNEW %d %d", r1, n);
-				break;
-			}
-
+				
 			case SETLIST: {
 				OPCODE_GET_TWO8bit_ONE10bit(inst, const uint32_t r1, uint32_t r2, const uint32_t r3);
 				#pragma unused(r3)
-				DUMP_VM(buffer, bindex, "SETLIST %d %d", r1, r2);
-				break;
-			}
-
-			case CLOSURE: {
-				OPCODE_GET_ONE8bit_ONE18bit(inst, const uint32_t r1, const uint32_t r2);
-				DUMP_VM(buffer, bindex, "CLOSURE %d %d", r1, r2);
+				DUMP_VM(buffer, bindex, "%s %d %d", opcode_name(op), r1, r2);
 				break;
 			}
-
+				
 			case CLOSE: {
 				OPCODE_GET_ONE8bit_ONE18bit(inst, const uint32_t r1, const uint32_t r2);
 				#pragma unused(r2)
-				DUMP_VM(buffer, bindex, "CLOSE %d", r1);
+				DUMP_VM(buffer, bindex, "%s %d", opcode_name(op), r1);
 				break;
 			}
-
+				
 			case RESERVED1:
 			case RESERVED2:
 			case RESERVED3:
@@ -286,12 +238,12 @@ const char *gravity_disassemble (const char *bcode, uint32_t blen, bool deserial
 				break;
 			}
 		}
-
+		
 		++pc;
 	}
-
+	
 	return buffer;
-
+	
 abort_disassemble:
 	if (ip && deserialize) mem_free(ip);
 	if (buffer) mem_free(buffer);

+ 1 - 1
src/utils/gravity_debug.h

@@ -13,6 +13,6 @@
 
 const char *opcode_constname (int n);
 const char *opcode_name (opcode_t op);
-const char *gravity_disassemble (const char *bcode, uint32_t blen, bool deserialize);
+const char *gravity_disassemble (gravity_vm *vm, gravity_function_t *f, const char *bcode, uint32_t blen, bool deserialize);
 
 #endif