(a, op, b)
| 561 | // Given two values and an operation, returns the result of that operation. |
| 562 | // Tries to do as much as possible at compile time. |
| 563 | function getFastValue(a, op, b) { |
| 564 | // In the past we supported many operations, but today we only use addition. |
| 565 | assert(op == '+'); |
| 566 | |
| 567 | // Convert 'true' and 'false' to '1' and '0'. |
| 568 | a = a === 'true' ? '1' : a === 'false' ? '0' : a; |
| 569 | b = b === 'true' ? '1' : b === 'false' ? '0' : b; |
| 570 | |
| 571 | let aNumber = null; |
| 572 | let bNumber = null; |
| 573 | if (typeof a == 'number') { |
| 574 | aNumber = a; |
| 575 | a = a.toString(); |
| 576 | } else if (isNumber(a)) { |
| 577 | aNumber = parseFloat(a); |
| 578 | } |
| 579 | if (typeof b == 'number') { |
| 580 | bNumber = b; |
| 581 | b = b.toString(); |
| 582 | } else if (isNumber(b)) { |
| 583 | bNumber = parseFloat(b); |
| 584 | } |
| 585 | |
| 586 | // First check if we can do the addition at compile time |
| 587 | if (aNumber !== null && bNumber !== null) { |
| 588 | return (aNumber + bNumber).toString(); |
| 589 | } |
| 590 | |
| 591 | // If one of them is a number, keep it last |
| 592 | if (aNumber !== null) { |
| 593 | const c = b; |
| 594 | b = a; |
| 595 | a = c; |
| 596 | const cNumber = bNumber; |
| 597 | bNumber = aNumber; |
| 598 | aNumber = cNumber; |
| 599 | } |
| 600 | |
| 601 | if (aNumber === 0) { |
| 602 | return b; |
| 603 | } else if (bNumber === 0) { |
| 604 | return a; |
| 605 | } |
| 606 | |
| 607 | if (b[0] === '-') { |
| 608 | op = '-'; |
| 609 | b = b.slice(1); |
| 610 | } |
| 611 | |
| 612 | return `(${a})${op}(${b})`; |
| 613 | } |
| 614 | |
| 615 | function calcFastOffset(ptr, pos) { |
| 616 | return getFastValue(ptr, '+', pos); |
no test coverage detected