| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent daf26d2 commit de0d99f
1 file changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -15,10 +15,17 @@ | |||
| 15 | 15 | */ | |
| 16 | 16 | ||
| 17 | 17 | // | |
| 18 | - // Lowers i64s to i32s by splitting variables and arguments | ||
| 19 | - // into pairs of i32s. i64 return values are lowered by | ||
| 20 | - // returning the low half and storing the high half into a | ||
| 21 | - // global. | ||
| 18 | + // Lowers i64s to i32s by splitting variables and arguments into pairs of i32s. | ||
| 19 | + // i64 return values are lowered by returning the low half and storing the high | ||
| 20 | + // half into a global. | ||
| 21 | + // | ||
| 22 | + // Note: This pass is designed primarily as an internal part of the wasm2js | ||
| 23 | + // pipeline rather than a general-purpose lowering pass for standard WebAssembly | ||
| 24 | + // runtimes. As such, it does not strictly preserve all WebAssembly trapping | ||
| 25 | + // semantics. In particular, float-to-int conversions are lowered using float | ||
| 26 | + // arithmetic and 32-bit truncations that do not trap on out-of-range values, | ||
| 27 | + // NaN, or infinity, relying on the fact that wasm2js maps 32-bit truncations | ||
| 28 | + // to non-trapping JavaScript bitwise operations (~~ and >>>). | ||
| 22 | 29 | // | |
| 23 | 30 | ||
| 24 | 31 | #include "abi/js.h" | |
@@ -623,8 +630,8 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> { | |||
| 623 | 630 | } | |
| 624 | 631 | ||
| 625 | 632 | void lowerReinterpretFloat64(Unary* curr) { | |
| 626 | - // Assume that the wasm file assumes the address 0 is invalid and roundtrip | ||
| 627 | - // our f64 through memory at address 0 | ||
| 633 | + // Roundtrip the f64 through a scratch buffer via wasm2js helper functions | ||
| 634 | + // to extract the low and high 32-bit integer halves. | ||
| 628 | 635 | TempVar highBits = getTemp(); | |
| 629 | 636 | Block* result = builder->blockify( | |
| 630 | 637 | builder->makeCall( | |
@@ -643,8 +650,8 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> { | |||
| 643 | 650 | } | |
| 644 | 651 | ||
| 645 | 652 | void lowerReinterpretInt64(Unary* curr) { | |
| 646 | - // Assume that the wasm file assumes the address 0 is invalid and roundtrip | ||
| 647 | - // our i64 through memory at address 0 | ||
| 653 | + // Roundtrip the low and high 32-bit integer halves through a scratch buffer | ||
| 654 | + // via wasm2js helper functions to reconstruct the f64 value. | ||
| 648 | 655 | TempVar highBits = fetchOutParam(curr->value); | |
| 649 | 656 | Block* result = builder->blockify( | |
| 650 | 657 | builder->makeCall(ABI::wasm2js::SCRATCH_STORE_I32, | |
@@ -661,6 +668,16 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> { | |||
| 661 | 668 | } | |
| 662 | 669 | ||
| 663 | 670 | void lowerTruncFloatToInt(Unary* curr) { | |
| 671 | + // Lowers 64-bit float-to-int truncations into 32-bit float arithmetic and | ||
| 672 | + // 32-bit truncations. | ||
| 673 | + // | ||
| 674 | + // Note that this lowering is non-trapping: in wasm2js, the emitted | ||
| 675 | + // 32-bit truncations are translated to JavaScript bitwise operations | ||
| 676 | + // ((~~expr) >>> 0), so out-of-range values, NaN, and +/-infinity do not | ||
| 677 | + // trap. Both signed and unsigned operations share the same logic because | ||
| 678 | + // the two's complement bit representation is identical for in-range values. | ||
| 679 | + // | ||
| 680 | + // Pseudocode: | ||
| 664 | 681 | // hiBits = if abs(f) >= 1.0 { | |
| 665 | 682 | // if f > 0.0 { | |
| 666 | 683 | // (unsigned) min( | |
| Back | FazBrowse Home | New Git URL |
0 commit comments