Browse code

More fixes for pdf.cbc.

Török Edvin authored on 2010/03/30 03:06:47
Showing 4 changed files
... ...
@@ -1542,6 +1542,25 @@ static inline int64_t ptr_compose(int32_t id, uint32_t offset)
1542 1542
     return (i << 32) | offset;
1543 1543
 }
1544 1544
 
1545
+static inline int get_geptypesize(const struct cli_bc *bc, uint16_t tid)
1546
+{
1547
+  const struct cli_bc_type *ty;
1548
+  if (tid >= bc->num_types+65) {
1549
+    cli_errmsg("bytecode: typeid out of range %u >= %u\n", tid, bc->num_types);
1550
+    return -1;
1551
+  }
1552
+  if (tid <= 64) {
1553
+    cli_errmsg("bytecode: invalid type for gep (%u)\n", tid);
1554
+    return -1;
1555
+  }
1556
+  ty = &bc->types[tid - 65];
1557
+  if (ty->kind != DPointerType) {
1558
+    cli_errmsg("bytecode: invalid gep type, must be pointer: %u\n", tid);
1559
+    return -1;
1560
+  }
1561
+  return typesize(bc, ty->containedTypes[0]);
1562
+}
1563
+
1545 1564
 static int cli_bytecode_prepare_interpreter(struct cli_bc *bc)
1546 1565
 {
1547 1566
     unsigned i, j, k;
... ...
@@ -1736,6 +1755,16 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc)
1736 1736
 		    MAPPTR(inst->u.unaryop);
1737 1737
 		    break;
1738 1738
 		case OP_BC_GEP1:
1739
+		    if (bcfunc->types[inst->u.binop[1]]&0x8000) {
1740
+                      cli_errmsg("bytecode: gep1 of alloca is not allowed\n");
1741
+                      return CL_EBYTECODE;
1742
+                    }
1743
+		    MAP(inst->u.three[1]);
1744
+		    MAP(inst->u.three[2]);
1745
+                    inst->u.three[0] = get_geptypesize(bc, inst->u.three[0]);
1746
+                    if (inst->u.three[0] == -1)
1747
+                      return CL_EBYTECODE;
1748
+                    break;
1739 1749
 		case OP_BC_GEPZ:
1740 1750
 		    /*three[0] is the type*/
1741 1751
 		    if (bcfunc->types[inst->u.three[1]]&0x8000)
... ...
@@ -1756,11 +1785,10 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc)
1756 1756
 		    MAPPTR(inst->u.three[1]);
1757 1757
 		    MAP(inst->u.three[2]);
1758 1758
 		    break;
1759
+		case OP_BC_RET_VOID:
1759 1760
 		case OP_BC_ISBIGENDIAN:
1760
-		    /*TODO */
1761
-		    break;
1762 1761
 		case OP_BC_ABORT:
1763
-		    /* TODO */
1762
+		    /* no operands */
1764 1763
 		    break;
1765 1764
 		case OP_BC_BSWAP16:
1766 1765
 		case OP_BC_BSWAP32:
... ...
@@ -1768,7 +1796,11 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc)
1768 1768
 		    MAP(inst->u.unaryop);
1769 1769
 		    break;
1770 1770
 		case OP_BC_PTRDIFF32:
1771
-		    /*TODO */
1771
+		    MAPPTR(inst->u.binop[0]);
1772
+		    MAPPTR(inst->u.binop[1]);
1773
+		    break;
1774
+		case OP_BC_PTRTOINT64:
1775
+		    MAPPTR(inst->u.unaryop);
1772 1776
 		    break;
1773 1777
 		default:
1774 1778
 		    cli_dbgmsg("Unhandled opcode: %d\n", inst->opcode);
... ...
@@ -100,7 +100,7 @@ static always_inline int jump(const struct cli_bc_func *func, uint16_t bbid, str
100 100
     return 0;
101 101
 }
102 102
 
103
-#define STACK_CHUNKSIZE 16384
103
+#define STACK_CHUNKSIZE 32768
104 104
 
105 105
 struct stack_chunk {
106 106
     struct stack_chunk *prev;
... ...
@@ -485,6 +485,18 @@ static inline int64_t ptr_compose(int32_t id, uint32_t offset)
485 485
     return (i << 32) | offset;
486 486
 }
487 487
 
488
+static inline int32_t ptr_diff32(int64_t ptr1, int64_t ptr2)
489
+{
490
+    int32_t ptrid1 = ptr1 >> 32;
491
+    int32_t ptrid2 = ptr2 >> 32;
492
+    if (ptrid1 != ptrid2) {
493
+	bcfail("difference of pointers not pointing to same object!", ptrid1, ptrid2, __FILE__, __LINE__);
494
+	/* invalid diff */
495
+	return 0x40000000;
496
+    }
497
+    return (uint32_t)ptr1 - (uint32_t)ptr2;
498
+}
499
+
488 500
 static inline int64_t ptr_register_stack(struct ptr_infos *infos,
489 501
 					 unsigned char *values,
490 502
 					 uint32_t off, uint32_t size)
... ...
@@ -643,7 +655,7 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
643 643
 	    if (tv1.tv_sec > timeout.tv_sec ||
644 644
 		(tv1.tv_sec == timeout.tv_sec &&
645 645
 		 tv1.tv_usec > timeout.tv_usec)) {
646
-		cli_warnmsg("Bytecode run timed out in interpreter\n");
646
+		cli_warnmsg("Bytecode run timed out in interpreter after %u opcodes\n", pc);
647 647
 		stop = CL_ETIMEOUT;
648 648
 		break;
649 649
 	    }
... ...
@@ -948,8 +960,8 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
948 948
 	    case OP_BC_COPY*5+4:
949 949
 	    {
950 950
 		uint64_t op;
951
-		READ32(op, BINOP(0));
952
-		WRITE32(BINOP(1), op);
951
+		READ64(op, BINOP(0));
952
+		WRITE64(BINOP(1), op);
953 953
 		break;
954 954
 	    }
955 955
 
... ...
@@ -1111,6 +1123,41 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
1111 1111
 		WRITE64(inst->dest, cbswap64(arg1));
1112 1112
 		break;
1113 1113
 	    }
1114
+	    DEFINE_OP(OP_BC_PTRDIFF32) {
1115
+		int64_t ptr1, ptr2;
1116
+		if (BINOP(0)&0x40000000)
1117
+		    ptr1 = ptr_compose(stackid, BINOP(0)&0xbfffffff);
1118
+		else
1119
+		    READ64(ptr1, BINOP(0));
1120
+		if (BINOP(1)&0x40000000)
1121
+		    ptr2 = ptr_compose(stackid, BINOP(1)&0xbfffffff);
1122
+		else
1123
+		    READ64(ptr2, BINOP(1));
1124
+		WRITE32(inst->dest, ptr_diff32(ptr1, ptr2));
1125
+		break;
1126
+	    }
1127
+	    DEFINE_OP(OP_BC_PTRTOINT64) {
1128
+		int64_t ptr;
1129
+		if (inst->u.unaryop&0x40000000)
1130
+		    ptr = ptr_compose(stackid, inst->u.unaryop&0xbfffffff);
1131
+		else
1132
+		    READ64(ptr, BINOP(0));
1133
+		WRITE64(inst->dest, ptr);
1134
+		break;
1135
+	    }
1136
+	    DEFINE_OP(OP_BC_GEP1) {
1137
+		int64_t ptr;
1138
+		if (!(inst->interp_op%5)) {
1139
+		    int32_t off;
1140
+		    READ32(off, inst->u.three[2]);
1141
+		    WRITE64(inst->dest, ptr_compose(stackid,
1142
+						    inst->u.three[1]+off));
1143
+		} else {
1144
+		    READ64(ptr, inst->u.three[1]);
1145
+		    WRITE64(inst->dest, ptr);
1146
+		}
1147
+		break;
1148
+	    }
1114 1149
 	    /* TODO: implement OP_BC_GEP1, OP_BC_GEP2, OP_BC_GEPN */
1115 1150
 	    default:
1116 1151
 		cli_errmsg("Opcode %u of type %u is not implemented yet!\n",
... ...
@@ -1128,8 +1175,8 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
1128 1128
 	gettimeofday(&tv1, NULL);
1129 1129
 	tv1.tv_sec -= tv0.tv_sec;
1130 1130
 	tv1.tv_usec -= tv0.tv_usec;
1131
-	cli_dbgmsg("intepreter bytecode run finished in %luus\n",
1132
-		   tv1.tv_sec*1000000 + tv1.tv_usec);
1131
+	cli_dbgmsg("intepreter bytecode run finished in %luus, after executing %u opcodes\n",
1132
+		   tv1.tv_sec*1000000 + tv1.tv_usec, pc);
1133 1133
     }
1134 1134
 
1135 1135
     cli_stack_destroy(&stack);
... ...
@@ -982,6 +982,7 @@ public:
982 982
 			case OP_BC_COPY:
983 983
 			case OP_BC_RET:
984 984
 			case OP_BC_PTRDIFF32:
985
+			case OP_BC_PTRTOINT64:
985 986
 			    // these instructions represents operands differently
986 987
 			    break;
987 988
 			default:
... ...
@@ -1333,6 +1334,13 @@ public:
1333 1333
 				Store(inst->dest, R);
1334 1334
 				break;
1335 1335
 			    }
1336
+			case OP_BC_PTRTOINT64:
1337
+			    {
1338
+				Value *P1 = convertOperand(func, inst, inst->u.unaryop);
1339
+				P1 = Builder.CreatePtrToInt(P1, Type::getInt64Ty(Context));
1340
+				Store(inst->dest, P1);
1341
+				break;
1342
+			    }
1336 1343
 			default:
1337 1344
 			    errs() << MODULE << "JIT doesn't implement opcode " <<
1338 1345
 				inst->opcode << " yet!\n";
... ...
@@ -87,6 +87,7 @@ enum bc_opcode {
87 87
   OP_BC_BSWAP32,
88 88
   OP_BC_BSWAP64,
89 89
   OP_BC_PTRDIFF32,
90
+  OP_BC_PTRTOINT64,
90 91
   OP_BC_INVALID /* last */
91 92
 };
92 93
 
... ...
@@ -112,8 +113,8 @@ static const unsigned char operand_counts[] = {
112 112
   3, 3, 3, 3,
113 113
   /* OP_BC_ISBIGENDIAN */
114 114
   0,
115
-  /* OP_BC_ABORT, OP_BSWAP*, OP_PTRDIFF32 */
116
-  0, 1, 1, 1, 2
115
+  /* OP_BC_ABORT, OP_BSWAP*, OP_PTRDIFF32, OP_PTRINT64 */
116
+  0, 1, 1, 1, 2, 1
117 117
 };
118 118
 
119 119
 enum bc_global {