|
25 | 25 | # pragma STDC FP_CONTRACT OFF |
26 | 26 | #endif |
27 | 27 |
|
| 28 | +#if defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1800 |
| 29 | +# include <float.h> |
| 30 | +# define isfinite _finite |
| 31 | +#elif defined(__sun) && defined(__SVR4) //Solaris |
| 32 | +# include <ieeefp.h> |
| 33 | +# define isfinite finite |
| 34 | +#else |
| 35 | +# define isfinite std::isfinite |
| 36 | +#endif |
| 37 | + |
28 | 38 |
|
29 | 39 | constexpr size_t UUID_STR_LENGTH = 37; |
30 | 40 | constexpr int UUID_BYTES = 16; |
@@ -195,22 +205,25 @@ static int _lsl_cast_internal(lua_State* L, bool in_list, bool neg_zero, bool ni |
195 | 205 | switch(to_lsl_type) |
196 | 206 | { |
197 | 207 | case LSLIType::LST_INTEGER: |
| 208 | + { |
198 | 209 | // If this seems weird, that's because it is. Mono truncates to 32-bit float |
199 | 210 | // before converting to integer. You'll note that we cast to int64_t first before |
200 | 211 | // truncating to int32_t, which also seems odd. We need that to emulate x86-64 |
201 | 212 | // integer wraparound on AArch64, or `print(((integer)((float)0x7FffFFfe)))` |
202 | 213 | // will print 2147483647 rather than -2147483648. See |
203 | 214 | // https://stackoverflow.com/questions/66279679/casting-float-to-int-with-wrap-around-on-aarch64-arm64 |
204 | | - if (std::isfinite(nvalue(val))) |
| 215 | + float nval = (float)nvalue(val); |
| 216 | + if (isfinite(nval)) |
205 | 217 | { |
206 | | - setintvalue(&new_tv, (int32_t)((int64_t)((float)nvalue(val)))); |
| 218 | + setintvalue(&new_tv, (int32_t)((int64_t)(nval))); |
207 | 219 | } |
208 | 220 | else |
209 | 221 | { |
210 | 222 | // Mono treats non-finite values as INT32_MIN. |
211 | 223 | setintvalue(&new_tv, INT32_MIN); |
212 | 224 | } |
213 | 225 | break; |
| 226 | + } |
214 | 227 | case LSLIType::LST_STRING: |
215 | 228 | { |
216 | 229 | // Again, truncates to float first. |
|
0 commit comments