aboutsummaryrefslogtreecommitdiffstats
path: root/src/ccl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ccl.c')
-rw-r--r--src/ccl.c115
1 files changed, 87 insertions, 28 deletions
diff --git a/src/ccl.c b/src/ccl.c
index ef059ffff25..86debeef0e5 100644
--- a/src/ccl.c
+++ b/src/ccl.c
@@ -1142,19 +1142,52 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1142 ccl_expr_self: 1142 ccl_expr_self:
1143 switch (op) 1143 switch (op)
1144 { 1144 {
1145 case CCL_PLUS: reg[rrr] += i; break; 1145 case CCL_PLUS: INT_ADD_WRAPV (reg[rrr], i, &reg[rrr]); break;
1146 case CCL_MINUS: reg[rrr] -= i; break; 1146 case CCL_MINUS: INT_SUBTRACT_WRAPV (reg[rrr], i, &reg[rrr]); break;
1147 case CCL_MUL: reg[rrr] *= i; break; 1147 case CCL_MUL: INT_MULTIPLY_WRAPV (reg[rrr], i, &reg[rrr]); break;
1148 case CCL_DIV: reg[rrr] /= i; break; 1148 case CCL_DIV:
1149 if (!i)
1150 CCL_INVALID_CMD;
1151 if (!INT_DIVIDE_OVERFLOW (reg[rrr], i))
1152 reg[rrr] /= i;
1153 break;
1149 case CCL_MOD: reg[rrr] %= i; break; 1154 case CCL_MOD: reg[rrr] %= i; break;
1155 if (!i)
1156 CCL_INVALID_CMD;
1157 reg[rrr] = i == -1 ? 0 : reg[rrr] % i;
1158 break;
1150 case CCL_AND: reg[rrr] &= i; break; 1159 case CCL_AND: reg[rrr] &= i; break;
1151 case CCL_OR: reg[rrr] |= i; break; 1160 case CCL_OR: reg[rrr] |= i; break;
1152 case CCL_XOR: reg[rrr] ^= i; break; 1161 case CCL_XOR: reg[rrr] ^= i; break;
1153 case CCL_LSH: reg[rrr] <<= i; break; 1162 case CCL_LSH:
1154 case CCL_RSH: reg[rrr] >>= i; break; 1163 if (i < 0)
1155 case CCL_LSH8: reg[rrr] <<= 8; reg[rrr] |= i; break; 1164 CCL_INVALID_CMD;
1165 reg[rrr] = i < UINT_WIDTH ? (unsigned) reg[rrr] << i : 0;
1166 break;
1167 case CCL_RSH:
1168 if (i < 0)
1169 CCL_INVALID_CMD;
1170 reg[rrr] = reg[rrr] >> min (i, INT_WIDTH - 1);
1171 break;
1172 case CCL_LSH8:
1173 reg[rrr] = (unsigned) reg[rrr] << 8;
1174 reg[rrr] |= i;
1175 break;
1156 case CCL_RSH8: reg[7] = reg[rrr] & 0xFF; reg[rrr] >>= 8; break; 1176 case CCL_RSH8: reg[7] = reg[rrr] & 0xFF; reg[rrr] >>= 8; break;
1157 case CCL_DIVMOD: reg[7] = reg[rrr] % i; reg[rrr] /= i; break; 1177 case CCL_DIVMOD:
1178 if (!i)
1179 CCL_INVALID_CMD;
1180 if (i == -1)
1181 {
1182 reg[7] = 0;
1183 INT_SUBTRACT_WRAPV (0, reg[rrr], &reg[rrr]);
1184 }
1185 else
1186 {
1187 reg[7] = reg[rrr] % i;
1188 reg[rrr] /= i;
1189 }
1190 break;
1158 case CCL_LS: reg[rrr] = reg[rrr] < i; break; 1191 case CCL_LS: reg[rrr] = reg[rrr] < i; break;
1159 case CCL_GT: reg[rrr] = reg[rrr] > i; break; 1192 case CCL_GT: reg[rrr] = reg[rrr] > i; break;
1160 case CCL_EQ: reg[rrr] = reg[rrr] == i; break; 1193 case CCL_EQ: reg[rrr] = reg[rrr] == i; break;
@@ -1204,19 +1237,52 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1204 ccl_set_expr: 1237 ccl_set_expr:
1205 switch (op) 1238 switch (op)
1206 { 1239 {
1207 case CCL_PLUS: reg[rrr] = i + j; break; 1240 case CCL_PLUS: INT_ADD_WRAPV (i, j, &reg[rrr]); break;
1208 case CCL_MINUS: reg[rrr] = i - j; break; 1241 case CCL_MINUS: INT_SUBTRACT_WRAPV (i, j, &reg[rrr]); break;
1209 case CCL_MUL: reg[rrr] = i * j; break; 1242 case CCL_MUL: INT_MULTIPLY_WRAPV (i, j, &reg[rrr]); break;
1210 case CCL_DIV: reg[rrr] = i / j; break; 1243 case CCL_DIV:
1211 case CCL_MOD: reg[rrr] = i % j; break; 1244 if (!j)
1245 CCL_INVALID_CMD;
1246 if (!INT_DIVIDE_OVERFLOW (i, j))
1247 i /= j;
1248 reg[rrr] = i;
1249 break;
1250 case CCL_MOD:
1251 if (!j)
1252 CCL_INVALID_CMD;
1253 reg[rrr] = j == -1 ? 0 : i % j;
1254 break;
1212 case CCL_AND: reg[rrr] = i & j; break; 1255 case CCL_AND: reg[rrr] = i & j; break;
1213 case CCL_OR: reg[rrr] = i | j; break; 1256 case CCL_OR: reg[rrr] = i | j; break;
1214 case CCL_XOR: reg[rrr] = i ^ j; break; 1257 case CCL_XOR: reg[rrr] = i ^ j; break;
1215 case CCL_LSH: reg[rrr] = i << j; break; 1258 case CCL_LSH:
1216 case CCL_RSH: reg[rrr] = i >> j; break; 1259 if (j < 0)
1217 case CCL_LSH8: reg[rrr] = (i << 8) | j; break; 1260 CCL_INVALID_CMD;
1261 reg[rrr] = j < UINT_WIDTH ? (unsigned) i << j : 0;
1262 break;
1263 case CCL_RSH:
1264 if (j < 0)
1265 CCL_INVALID_CMD;
1266 reg[rrr] = i >> min (j, INT_WIDTH - 1);
1267 break;
1268 case CCL_LSH8:
1269 reg[rrr] = ((unsigned) i << 8) | j;
1270 break;
1218 case CCL_RSH8: reg[rrr] = i >> 8; reg[7] = i & 0xFF; break; 1271 case CCL_RSH8: reg[rrr] = i >> 8; reg[7] = i & 0xFF; break;
1219 case CCL_DIVMOD: reg[rrr] = i / j; reg[7] = i % j; break; 1272 case CCL_DIVMOD:
1273 if (!j)
1274 CCL_INVALID_CMD;
1275 if (j == -1)
1276 {
1277 INT_SUBTRACT_WRAPV (0, reg[rrr], &reg[rrr]);
1278 reg[7] = 0;
1279 }
1280 else
1281 {
1282 reg[rrr] = i / j;
1283 reg[7] = i % j;
1284 }
1285 break;
1220 case CCL_LS: reg[rrr] = i < j; break; 1286 case CCL_LS: reg[rrr] = i < j; break;
1221 case CCL_GT: reg[rrr] = i > j; break; 1287 case CCL_GT: reg[rrr] = i > j; break;
1222 case CCL_EQ: reg[rrr] = i == j; break; 1288 case CCL_EQ: reg[rrr] = i == j; break;
@@ -1225,7 +1291,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1225 case CCL_NE: reg[rrr] = i != j; break; 1291 case CCL_NE: reg[rrr] = i != j; break;
1226 case CCL_DECODE_SJIS: 1292 case CCL_DECODE_SJIS:
1227 { 1293 {
1228 i = (i << 8) | j; 1294 i = ((unsigned) i << 8) | j;
1229 SJIS_TO_JIS (i); 1295 SJIS_TO_JIS (i);
1230 reg[rrr] = i >> 8; 1296 reg[rrr] = i >> 8;
1231 reg[7] = i & 0xFF; 1297 reg[7] = i & 0xFF;
@@ -1233,7 +1299,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1233 } 1299 }
1234 case CCL_ENCODE_SJIS: 1300 case CCL_ENCODE_SJIS:
1235 { 1301 {
1236 i = (i << 8) | j; 1302 i = ((unsigned) i << 8) | j;
1237 JIS_TO_SJIS (i); 1303 JIS_TO_SJIS (i);
1238 reg[rrr] = i >> 8; 1304 reg[rrr] = i >> 8;
1239 reg[7] = i & 0xFF; 1305 reg[7] = i & 0xFF;
@@ -2219,15 +2285,8 @@ Return index number of the registered CCL program. */)
2219 /* Extend the table. */ 2285 /* Extend the table. */
2220 Vccl_program_table = larger_vector (Vccl_program_table, 1, -1); 2286 Vccl_program_table = larger_vector (Vccl_program_table, 1, -1);
2221 2287
2222 { 2288 ASET (Vccl_program_table, idx,
2223 Lisp_Object elt = make_uninit_vector (4); 2289 CALLN (Fvector, name, ccl_prog, resolved, Qt));
2224
2225 ASET (elt, 0, name);
2226 ASET (elt, 1, ccl_prog);
2227 ASET (elt, 2, resolved);
2228 ASET (elt, 3, Qt);
2229 ASET (Vccl_program_table, idx, elt);
2230 }
2231 2290
2232 Fput (name, Qccl_program_idx, make_fixnum (idx)); 2291 Fput (name, Qccl_program_idx, make_fixnum (idx));
2233 return make_fixnum (idx); 2292 return make_fixnum (idx);