|
351 | 351 | CLEAR(series->data, SERIES_WIDE(series)); // terminate
|
352 | 352 | } else {
|
353 | 353 | // Add bias to head:
|
354 |
| - SERIES_ADD_BIAS(series, len); |
355 |
| - SERIES_REST(series) -= len; |
356 |
| - series->data += SERIES_WIDE(series) * len; |
357 |
| - if (NZ(start = SERIES_BIAS(series))) { |
358 |
| - // If more than half biased: |
359 |
| - if (start >= MAX_SERIES_BIAS || start > SERIES_REST(series)) |
360 |
| - Reset_Bias(series); |
| 354 | + REBCNT bias = SERIES_BIAS(series); |
| 355 | + if (REB_U32_ADD_OF(bias, len, &bias)) { |
| 356 | + Trap0(RE_OVERFLOW); |
| 357 | + } |
| 358 | + if (bias > 0xffff) { //bias is 16-bit, so a simple SERIES_ADD_BIAS could overflow it |
| 359 | + REBYTE *data = series->data; |
| 360 | + |
| 361 | + data += SERIES_WIDE(series) * len; |
| 362 | + series->data -= SERIES_WIDE(series) * SERIES_BIAS(series); |
| 363 | + SERIES_REST(series) += bias; |
| 364 | + SERIES_SET_BIAS(series, 0); |
| 365 | + |
| 366 | + memmove(series->data, data, SERIES_USED(series)); |
| 367 | + } else { |
| 368 | + SERIES_SET_BIAS(series, bias); |
| 369 | + SERIES_REST(series) -= len; |
| 370 | + series->data += SERIES_WIDE(series) * len; |
| 371 | + if (NZ(start = SERIES_BIAS(series))) { |
| 372 | + // If more than half biased: |
| 373 | + if (start >= MAX_SERIES_BIAS || start > SERIES_REST(series)) |
| 374 | + Reset_Bias(series); |
| 375 | + } |
361 | 376 | }
|
362 | 377 | }
|
363 | 378 | return;
|
|
0 commit comments