| 668 | #endif |
| 669 | |
| 670 | void fx_String_fromCharCode(txMachine* the) |
| 671 | { |
| 672 | txInteger length = 0; |
| 673 | txInteger count = mxArgc; |
| 674 | txInteger index = 0; |
| 675 | txInteger c; |
| 676 | txString p; |
| 677 | while (index < count) { |
| 678 | txSlot *slot = mxArgv(index); |
| 679 | if (XS_INTEGER_KIND != slot->kind) { |
| 680 | txNumber number = fxToNumber(the, slot); |
| 681 | switch (c_fpclassify(number)) { |
| 682 | case C_FP_INFINITE: |
| 683 | case C_FP_NAN: |
| 684 | case C_FP_ZERO: |
| 685 | slot->value.integer = 0; |
| 686 | break; |
| 687 | default: |
| 688 | #define MODULO 65536.0 |
| 689 | number = c_fmod(c_trunc(number), MODULO); |
| 690 | if (number < 0) |
| 691 | number += MODULO; |
| 692 | slot->value.integer = (txInteger)number; |
| 693 | break; |
| 694 | } |
| 695 | slot->kind = XS_INTEGER_KIND; |
| 696 | } |
| 697 | else { |
| 698 | txInteger integer = slot->value.integer % 65536; |
| 699 | if (integer < 0) |
| 700 | integer += 65536; |
| 701 | slot->value.integer = integer; |
| 702 | } |
| 703 | index++; |
| 704 | } |
| 705 | index = 0; |
| 706 | while (index < count) { |
| 707 | c = mxArgv(index)->value.integer; |
| 708 | index++; |
| 709 | if (index < count) { |
| 710 | txInteger d = mxArgv(index)->value.integer; |
| 711 | if ((0x0000D800 <= c) && (c <= 0x0000DBFF) && (0x0000DC00 <= d) && (d <= 0x0000DFFF)) { |
| 712 | c = 0x00010000 + ((c & 0x000003FF) << 10) + (d & 0x000003FF); |
| 713 | index++; |
| 714 | } |
| 715 | } |
| 716 | length += mxStringByteLength(c); |
| 717 | } |
| 718 | mxMeterSome(count); |
| 719 | mxResult->value.string = (txString)fxNewChunk(the, length + 1); |
| 720 | mxResult->kind = XS_STRING_KIND; |
| 721 | p = mxResult->value.string; |
| 722 | index = 0; |
| 723 | while (index < count) { |
| 724 | c = mxArgv(index)->value.integer; |
| 725 | index++; |
| 726 | if (index < count) { |
| 727 | txInteger d = mxArgv(index)->value.integer; |
nothing calls this directly
no test coverage detected