diff options
Diffstat (limited to 'src/ccl.c')
| -rw-r--r-- | src/ccl.c | 115 |
1 files changed, 87 insertions, 28 deletions
| @@ -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, ®[rrr]); break; |
| 1146 | case CCL_MINUS: reg[rrr] -= i; break; | 1146 | case CCL_MINUS: INT_SUBTRACT_WRAPV (reg[rrr], i, ®[rrr]); break; |
| 1147 | case CCL_MUL: reg[rrr] *= i; break; | 1147 | case CCL_MUL: INT_MULTIPLY_WRAPV (reg[rrr], i, ®[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], ®[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, ®[rrr]); break; |
| 1208 | case CCL_MINUS: reg[rrr] = i - j; break; | 1241 | case CCL_MINUS: INT_SUBTRACT_WRAPV (i, j, ®[rrr]); break; |
| 1209 | case CCL_MUL: reg[rrr] = i * j; break; | 1242 | case CCL_MUL: INT_MULTIPLY_WRAPV (i, j, ®[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], ®[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); |